diff --git a/gradle.properties b/gradle.properties index 66d7e44..fe5a2e3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,4 +8,4 @@ name=StorageUtils authors=AlphaConqueror description=Utilities for data storage. version_major=1 -version_minor=6 +version_minor=7 diff --git a/src/main/java/net/dirtcraft/storageutils/hibernate/AbstractHibernateStorage.java b/src/main/java/net/dirtcraft/storageutils/hibernate/AbstractHibernateStorage.java index 6b09441..096436a 100644 --- a/src/main/java/net/dirtcraft/storageutils/hibernate/AbstractHibernateStorage.java +++ b/src/main/java/net/dirtcraft/storageutils/hibernate/AbstractHibernateStorage.java @@ -87,6 +87,8 @@ public R performTask(final HibernateStorage.@NonNull ResultTask task) final R result = task.execute(taskContext); transaction.commit(); + // marks context closed soo no context actions are done in queue + taskContext.markClosed(); // execute tasks after transaction was successfully committed taskContext.executeTasks(); @@ -94,6 +96,9 @@ public R performTask(final HibernateStorage.@NonNull ResultTask task) } catch (final Exception e) { if (transaction.isActive()) { transaction.rollback(); + + taskContext.markClosed(); + taskContext.executeRollbackTasks(); } @@ -123,6 +128,8 @@ public R performTask(final HibernateStorage.@NonNull ResultTask task) } throw new CompletionException(e); + } finally { + taskContext.markClosed(); } } } catch (final JDBCConnectionException e) { diff --git a/src/main/java/net/dirtcraft/storageutils/taskcontext/StandardTaskContext.java b/src/main/java/net/dirtcraft/storageutils/taskcontext/StandardTaskContext.java index 7d3cb66..07d8eaf 100644 --- a/src/main/java/net/dirtcraft/storageutils/taskcontext/StandardTaskContext.java +++ b/src/main/java/net/dirtcraft/storageutils/taskcontext/StandardTaskContext.java @@ -20,12 +20,16 @@ public class StandardTaskContext implements TaskContext { @NonNull private final Queue rollbackQueue = new LinkedList<>(); + private final Thread owner = Thread.currentThread(); + private volatile boolean closed = false; + public StandardTaskContext(@NonNull final Session session) { this.session = session; } @Override public @NonNull Session session() { + this.checkUse(); return this.session; } @@ -52,4 +56,20 @@ public void executeRollbackTasks() { this.rollbackQueue.poll().run(); } } + + @Override + public void markClosed() { + this.closed = true; + } + + @Override + public void checkUse() { + if (closed) { + throw new IllegalStateException("TaskContext used after task finished"); + } + + if (Thread.currentThread() != owner) { + throw new IllegalStateException("TaskContext used from non-owner thread"); + } + } } diff --git a/src/main/java/net/dirtcraft/storageutils/taskcontext/TaskContext.java b/src/main/java/net/dirtcraft/storageutils/taskcontext/TaskContext.java index 1b2a0d0..6b44219 100644 --- a/src/main/java/net/dirtcraft/storageutils/taskcontext/TaskContext.java +++ b/src/main/java/net/dirtcraft/storageutils/taskcontext/TaskContext.java @@ -42,4 +42,14 @@ public interface TaskContext { * Executes the runnable tasks upon rollback. */ void executeRollbackTasks(); + + /** + * Marks context as closed. + */ + void markClosed(); + + /** + * Check if context is used after close. + */ + void checkUse(); }