JTA事务和JDBC事务
一般情况下,J2EE应用服务器支持JDBC事务、JTA事务、容器管理事务。这里讨论JTA和JDBC事务的区别。这2个是常用的DAO模式事务界定方式。
JDBC 事务
JDBC 事务是用 Connection 对象控制的。JDBC Connection 接口( java.sql.Connection )提供了两种事务模式:自动提交和手工提交。
★ 在jdbc中,事务操作缺省是自动提交。也就是说,一条对数据库的更新表达式代表一项事务操作,操作成功后,系统将自动调用commit()来提交,否则将调用rollback()来回滚。
★ 在jdbc中,可以通过调用setAutoCommit(false)来禁止自动提交。之后就可以把多个数据库操作的表达式作为一个事务,在操作完成后调用commit()来进行整体提交,倘若其中一个表达式操作失败,都不会执行到commit(),并且将产生响应的异常;此时就可以在异常捕获时调用 rollback()进行回滚。这样做可以保持多次更新操作后,相关数据的一致性,示例如下:
Java代码
1. try { 2. 3. conn = 4. 5. DriverManager.getConnection 6. 7. ("jdbc:oracle:thin:@host:1521:SID","username","userpwd"; 8. 9. conn.setAutoCommit(false);//禁止自动提交,设置回滚点 10. 11. stmt = conn.createStatement(); 12. 13. stmt.executeUpdate(“alter table …”); //数据库更新操作1 14. 15. stmt.executeUpdate(“insert into table …”); //数据库更新操作2 16. 17. conn.commit(); //事务提交 18. 19. }catch(Exception ex) { 20. 21. ex.printStackTrace(); 22. 23. try { 24. 25. conn.rollback(); //操作不成功则回滚 26. 27. }catch(Exception e) { 28. 29. e.printStackTrace(); 30. 31. } 32. 33. } try {conn = DriverManager.getConnection ("jdbc:oracle:thin:@host:1521:SID","username","userpwd"; conn.setAutoCommit(false);//禁止自动提交,设置回滚点 stmt = conn.createStatement();stmt.executeUpdate(“alter table …”); //数据库更新操作1stmt.executeUpdate(“insert into table …”); //数据库更新操作2 conn.commit(); //事务提交 }catch(Exception ex) { ex.printStackTrace(); try { conn.rollback(); //操作不成功则回滚 }catch(Exception e) {e.printStackTrace(); }}1. // ... 2. DataSource ds = obtainXADataSource(); 3. Connection conn = ds.getConnection(); 4. pstmt = conn.prepareStatement("UPDATE MOVIES ..."); 5. pstmt.setString(1, "Spinal Tap"); 6. pstmt.executeUpdate(); 7. // ... 8. utx.commit(); // ... DataSource ds = obtainXADataSource(); Connection conn = ds.getConnection(); pstmt = conn.prepareStatement("UPDATE MOVIES ..."); pstmt.setString(1, "Spinal Tap"); pstmt.executeUpdate(); // ... utx.commit(); 1. import javax.transaction.xa.*; 2. public class MyXid implements Xid 3. { 4. protected int formatId; 5. protected byte gtrid[]; 6. protected byte bqual[]; 7. public MyXid() 8. { 9. } 10. public MyXid(int formatId, byte gtrid[], byte bqual[]) 11. { 12. this.formatId = formatId; 13. this.gtrid = gtrid; 14. this.bqual = bqual; 15. } 16. 17. public int getFormatId() 18. { 19. return formatId; 20. } 21. 22. public byte[] getBranchQualifier() 23. { 24. return bqual; 25. } 26. 27. public byte[] getGlobalTransactionId() 28. { 29. return gtrid; 30. } 31. 32. } import javax.transaction.xa.*; public class MyXid implements Xid { protected int formatId; protected byte gtrid[]; protected byte bqual[]; public MyXid() { } public MyXid(int formatId, byte gtrid[], byte bqual[]) { this.formatId = formatId; this.gtrid = gtrid; this.bqual = bqual; } public int getFormatId() { return formatId; } public byte[] getBranchQualifier() { return bqual; } public byte[] getGlobalTransactionId() { return gtrid; } }其次,你需要创建一个你要使用的数据库的数据源:Java代码 收藏代码 1. public DataSource getDataSource() 2. throws SQLException 3. { 4. SQLServerDataSource xaDS = new 5. com.merant.datadirect.jdbcx.sqlserver.SQLServerDataSource(); 6. xaDS.setDataSourceName("SQLServer"); 7. xaDS.setServerName("server"); 8. xaDS.setPortNumber(1433); 9. xaDS.setSelectMethod("cursor"); 10. return xaDS; 11. } public DataSource getDataSource() throws SQLException { SQLServerDataSource xaDS = new com.merant.datadirect.jdbcx.sqlserver.SQLServerDataSource(); xaDS.setDataSourceName("SQLServer"); xaDS.setServerName("server"); xaDS.setPortNumber(1433); xaDS.setSelectMethod("cursor"); return xaDS; } 1. XADataSource xaDS; 2. XAConnection xaCon; 3. XAResource xaRes; 4. Xid xid; 5. Connection con; 6. Statement stmt; 7. int ret; 8. xaDS = getDataSource(); 9. xaCon = xaDS.getXAConnection("jdbc_user", "jdbc_password"); 10. xaRes = xaCon.getXAResource(); 11. con = xaCon.getConnection(); 12. stmt = con.createStatement(); 13. xid = new MyXid(100, new byte[]{0x01}, new byte[]{0x02}); 14. try { 15. xaRes.start(xid, XAResource.TMNOFLAGS); 16. stmt.executeUpdate("insert into test_table values (100)"); 17. xaRes.end(xid, XAResource.TMSUCCESS); 18. ret = xaRes.prepare(xid); 19. if (ret == XAResource.XA_OK) { 20. xaRes.commit(xid, false); 21. } 22. } 23. catch (XAException e) { 24. e.printStackTrace(); 25. } 26. finally { 27. stmt.close(); 28. con.close(); 29. xaCon.close(); 30. } XADataSource xaDS; XAConnection xaCon; XAResource xaRes; Xid xid; Connection con; Statement stmt; int ret; xaDS = getDataSource(); xaCon = xaDS.getXAConnection("jdbc_user", "jdbc_password"); xaRes = xaCon.getXAResource(); con = xaCon.getConnection(); stmt = con.createStatement(); xid = new MyXid(100, new byte[]{0x01}, new byte[]{0x02}); try { xaRes.start(xid, XAResource.TMNOFLAGS); stmt.executeUpdate("insert into test_table values (100)"); xaRes.end(xid, XAResource.TMSUCCESS); ret = xaRes.prepare(xid); if (ret == XAResource.XA_OK) { xaRes.commit(xid, false); } } catch (XAException e) { e.printStackTrace(); } finally { stmt.close(); con.close(); xaCon.close(); }