Java more than one DB connection in UserTransaction

前端 未结 5 791
被撕碎了的回忆
被撕碎了的回忆 2021-01-19 23:12
static void clean() throws Exception {
  final UserTransaction tx = InitialContext.doLookup(\"UserTransaction\");
  tx.begin();

  try {
    final DataSource ds = In         


        
5条回答
  •  遥遥无期
    2021-01-19 23:51

    Depending on your database this is quite a normal case.

    An object implementing UserTransaction interface represents a "logical transaction". It doesn't always map to a real, "physical" transaction that a database engine respects.
    For example, there are situations that cause implicit commits (as well as implicit starts) of transactions. In case of Oracle (can't vouch for other DBs), closing a connection is one of them.

    From Oracle's docs:

    "If the auto-commit mode is disabled and you close the connection without explicitly committing or rolling back your last changes, then an implicit COMMIT operation is run".

    But there can be other possible reasons for implicit commits: select for update, various locking statements, DDLs, and so on. They are database-specific.

    So, back to our code.
    The first transaction is committed by closing a connection. Then another transaction is implicitly started by the DML on the second connection. It inserts non-conflicting changes and the second connection.close() commits them without PK violation. tx.commit() won't even get a chance to commit anything (and how could it? the connection is already closed).

    The bottom line: "logical" transaction managers don't always give you the full picture.
    Sometimes transactions are started and committed without an explicit reason. And sometimes they are even ignored by a DB.

    PS: I assumed you used Oracle, but the said holds true for other databases as well. For example, MySQL's list of implicit commit reasons.

提交回复
热议问题