You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2017/02/20 08:43:45 UTC
cayenne git commit: CAY-2186 Always run MySQL PK generator in
separate transaction
Repository: cayenne
Updated Branches:
refs/heads/master 3d2b091b6 -> 4f4ade0ee
CAY-2186 Always run MySQL PK generator in separate transaction
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/4f4ade0e
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/4f4ade0e
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/4f4ade0e
Branch: refs/heads/master
Commit: 4f4ade0eead7ddafc59b21343d33abc5ffa5ae5a
Parents: 3d2b091
Author: Nikita Timofeev <st...@gmail.com>
Authored: Mon Feb 20 11:43:17 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Mon Feb 20 11:43:17 2017 +0300
----------------------------------------------------------------------
.../cayenne/dba/mysql/MySQLPkGenerator.java | 20 +++++++++++-
.../apache/cayenne/tx/CayenneTransaction.java | 5 +++
.../apache/cayenne/tx/ExternalTransaction.java | 5 +++
.../java/org/apache/cayenne/tx/Transaction.java | 5 +++
.../configuration/server/ServerRuntimeIT.java | 32 ++++++++++++++++++++
.../apache/cayenne/tx/UserTransactionIT.java | 5 +++
6 files changed, 71 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cayenne/blob/4f4ade0e/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLPkGenerator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLPkGenerator.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLPkGenerator.java
index 9e30749..9812f5f 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLPkGenerator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLPkGenerator.java
@@ -29,11 +29,17 @@ import org.apache.cayenne.access.DataNode;
import org.apache.cayenne.dba.JdbcAdapter;
import org.apache.cayenne.dba.JdbcPkGenerator;
import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.tx.BaseTransaction;
+import org.apache.cayenne.tx.Transaction;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
/**
*/
public class MySQLPkGenerator extends JdbcPkGenerator {
+ private static final Log logger = LogFactory.getLog(MySQLPkGenerator.class);
+
MySQLPkGenerator(JdbcAdapter adapter) {
super(adapter);
}
@@ -55,6 +61,15 @@ public class MySQLPkGenerator extends JdbcPkGenerator {
SQLException exception = null;
long pk = -1L;
+ // Start new transaction if needed, can any way lead to problems when
+ // using external transaction manager. We can only warn about it.
+ // See https://issues.apache.org/jira/browse/CAY-2186 for details.
+ Transaction transaction = BaseTransaction.getThreadTransaction();
+ if(transaction != null && transaction.isExternal()) {
+ logger.warn("Using MysqlPkGenerator with external transaction manager may lead to inconsistent state.");
+ }
+ BaseTransaction.bindThreadTransaction(null);
+
try (Connection con = node.getDataSource().getConnection()) {
if (con.getAutoCommit()) {
@@ -86,6 +101,8 @@ public class MySQLPkGenerator extends JdbcPkGenerator {
}
} catch (SQLException otherEx) {
exception = processSQLException(otherEx, null);
+ } finally {
+ BaseTransaction.bindThreadTransaction(transaction);
}
// check errors
@@ -118,7 +135,8 @@ public class MySQLPkGenerator extends JdbcPkGenerator {
@Override
protected String pkTableCreateString() {
return "CREATE TABLE IF NOT EXISTS AUTO_PK_SUPPORT " +
- "(TABLE_NAME CHAR(100) NOT NULL, NEXT_ID BIGINT NOT NULL, UNIQUE (TABLE_NAME))";
+ "(TABLE_NAME CHAR(100) NOT NULL, NEXT_ID BIGINT NOT NULL, UNIQUE (TABLE_NAME)) " +
+ "ENGINE=" + MySQLAdapter.DEFAULT_STORAGE_ENGINE;
}
/**
http://git-wip-us.apache.org/repos/asf/cayenne/blob/4f4ade0e/cayenne-server/src/main/java/org/apache/cayenne/tx/CayenneTransaction.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/tx/CayenneTransaction.java b/cayenne-server/src/main/java/org/apache/cayenne/tx/CayenneTransaction.java
index dba12d9..5554f07 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/tx/CayenneTransaction.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/tx/CayenneTransaction.java
@@ -131,4 +131,9 @@ public class CayenneTransaction extends BaseTransaction {
throw new CayenneRuntimeException(deferredException);
}
}
+
+ @Override
+ public boolean isExternal() {
+ return false;
+ }
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/4f4ade0e/cayenne-server/src/main/java/org/apache/cayenne/tx/ExternalTransaction.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/tx/ExternalTransaction.java b/cayenne-server/src/main/java/org/apache/cayenne/tx/ExternalTransaction.java
index 8fd4316..8afa94f 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/tx/ExternalTransaction.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/tx/ExternalTransaction.java
@@ -43,4 +43,9 @@ public class ExternalTransaction extends BaseTransaction {
protected void processRollback() {
logger.logRollbackTransaction("no rollback - transaction controlled externally.");
}
+
+ @Override
+ public boolean isExternal() {
+ return true;
+ }
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/4f4ade0e/cayenne-server/src/main/java/org/apache/cayenne/tx/Transaction.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/tx/Transaction.java b/cayenne-server/src/main/java/org/apache/cayenne/tx/Transaction.java
index f87e8c3..0f03007 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/tx/Transaction.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/tx/Transaction.java
@@ -63,4 +63,9 @@ public interface Transaction {
Map<String, Connection> getConnections();
void addListener(TransactionListener listener);
+
+ /**
+ * Is this transaction managed by external transaction manager
+ */
+ boolean isExternal();
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/4f4ade0e/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/ServerRuntimeIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/ServerRuntimeIT.java b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/ServerRuntimeIT.java
index 4668264..30b5e63 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/ServerRuntimeIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/ServerRuntimeIT.java
@@ -18,8 +18,10 @@
****************************************************************/
package org.apache.cayenne.configuration.server;
+import org.apache.cayenne.ObjectContext;
import org.apache.cayenne.PersistenceState;
import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.ObjectSelect;
import org.apache.cayenne.testdo.testmap.Artist;
import org.apache.cayenne.tx.Transaction;
import org.apache.cayenne.tx.TransactionListener;
@@ -45,6 +47,9 @@ public class ServerRuntimeIT extends ServerCase {
@Inject
private ServerRuntime runtime;
+ @Inject
+ private ObjectContext context;
+
@Test
public void testPerformInTransaction_Local_Callback() {
@@ -93,4 +98,31 @@ public class ServerRuntimeIT extends ServerCase {
verify(callback, times(0)).willCommit(any(Transaction.class));
}
}
+
+ @Test
+ public void testRollbackTransaction() {
+ assertEquals(0, ObjectSelect.query(Artist.class).selectCount(context));
+
+ try {
+ runtime.performInTransaction(new TransactionalOperation<Object>() {
+ @Override
+ public Object perform() {
+ // Default PK batch size is 20
+ for (int i = 0; i < 30; i++) {
+ Artist artist = context.newObject(Artist.class);
+ artist.setArtistName("test" + i);
+ context.commitChanges();
+ }
+
+ // this should fail with validation error
+ context.newObject(Artist.class);
+ context.commitChanges();
+ return null;
+ }
+ });
+ } catch (Exception ignored) {
+ }
+
+ assertEquals(0, ObjectSelect.query(Artist.class).selectCount(context));
+ }
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/4f4ade0e/cayenne-server/src/test/java/org/apache/cayenne/tx/UserTransactionIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/tx/UserTransactionIT.java b/cayenne-server/src/test/java/org/apache/cayenne/tx/UserTransactionIT.java
index 9d1338f..3097808 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/tx/UserTransactionIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/tx/UserTransactionIT.java
@@ -108,6 +108,11 @@ public class UserTransactionIT extends ServerCase {
public void addListener(TransactionListener listener) {
delegate.addListener(listener);
}
+
+ @Override
+ public boolean isExternal() {
+ return false;
+ }
}
}