在POJO中使用ThreadLocal的Java嵌套事务
大多數(shù)嵌套事務(wù)是使用EJB實(shí)現(xiàn)的,現(xiàn)在我們嘗試在POJO上實(shí)現(xiàn)嵌套事務(wù)。 在這里,我們使用了ThreadLocal的功能。
了解嵌套事務(wù)
事務(wù)可以嵌套在另一個(gè)內(nèi)部。 因此,內(nèi)部事務(wù)或外部事務(wù)可以回滾或提交,而不會(huì)影響其他事務(wù)。
創(chuàng)建新事務(wù)后,它將進(jìn)入外部事務(wù)。 一旦內(nèi)部事務(wù)以提交或回滾的方式完成,外部事務(wù)就可以執(zhí)行提交或回滾而與內(nèi)部事務(wù)無(wú)關(guān)。 首先關(guān)閉最里面的事務(wù),然后繼續(xù)進(jìn)行最外面的事務(wù)。
使用簡(jiǎn)單POJO實(shí)施
創(chuàng)建界面如下:
importjava.sql.Connection;publicinterfaceTransactionManager {Connection getConnection();voidbeginTransaction();void commit();void rollback(); }創(chuàng)建事務(wù)管理器類(lèi),如下所示:
importjava.sql.Connection; importjava.sql.DriverManager; importjava.sql.SQLException; importjava.util.Stack;publicclassTransactionManagerStackImplimplementsTransactionManager {private Stack<Connection>connections = new Stack<Connection>();@Overridepublic Connection getConnection() {if (connections.isEmpty()) {this.addConn();}returnconnections.peek();}@OverridepublicvoidbeginTransaction() {this.addConn();}@Overridepublicvoid commit() {try {if (connections.peek() != null&& !connections.peek().isClosed()) {System.out.println(connections.peek().toString() +"--Commit---");connections.peek().commit();connections.pop().close();}} catch (SQLException e) {e.printStackTrace();}}@Overridepublicvoid rollback() {try {if (connections.peek() != null&& !connections.peek().isClosed()) {System.out.println(connections.peek().toString() +"--Rollback---");connections.peek().rollback();connections.pop().close();}} catch (SQLException e) {e.printStackTrace();}}privatevoidaddConn() {try {Connection con = this.getMysqlConnection();con.setAutoCommit(false);connections.push(con);System.out.println(con.toString() +"--Conection---");} catch (SQLException e) {e.printStackTrace();}}private Connection getMysqlConnection() {returngetConnection("com.mysql.jdbc.Driver", "jdbc:mysql://localhost:3306/testdb", "test", "test12345");}private Connection getConnection(String driver, String connection,String user, String password) {try {Class.forName(driver);returnDriverManager.getConnection(connection, user, password);} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();}returnnull;} }在這里,我們創(chuàng)建了一個(gè)堆棧:
private Stack<Connection> connections = new Stack<Connection>();由于事務(wù)創(chuàng)建為L(zhǎng)IFO(堆棧),因此我們使用了Java API中的Stack來(lái)維護(hù)每個(gè)事務(wù)的連接:
public void beginTransaction()開(kāi)始事務(wù)以開(kāi)始新的事務(wù)并將連接添加到堆棧。 AutoCommit已設(shè)置為false:
public Connection getConnection()獲取當(dāng)前事務(wù)的連接。 如果不存在,它將創(chuàng)建并添加到堆棧中:
public void commit()提交當(dāng)前事務(wù)并關(guān)閉連接,該連接也已從堆棧中刪除:
public void rollback()回滾當(dāng)前事務(wù)并關(guān)閉連接,該連接也已從堆棧中刪除。
上面的TransactionManagerStackImpl類(lèi)將為單線程創(chuàng)建嵌套事務(wù)。
多線程的嵌套事務(wù)
對(duì)于多線程應(yīng)用程序,每個(gè)線程都有獨(dú)立的事務(wù)和嵌套事務(wù)。
我們提出使用ThreadLocal來(lái)管理連接棧。
importjava.sql.Connection;publicclassTransactionManagerThreadLocalimplementsTransactionManager {privatestaticfinalThreadLocal<TransactionManager>tranManager = newThreadLocal<TransactionManager>() {protectedTransactionManagerinitialValue() {System.out.println(this.toString() + "--Thread Local Initialize--");returnnewTransactionManagerStackImpl();}};@OverridepublicvoidbeginTransaction() {tranManager.get().beginTransaction();}@Overridepublicvoid commit() {tranManager.get().commit();}@Overridepublicvoid rollback() {tranManager.get().rollback();}@Overridepublic Connection getConnection() {returntranManager.get().getConnection();} }在這里,我們初始化TransactionManagerStackImpl以在線程內(nèi)部創(chuàng)建嵌套事務(wù)。
測(cè)試中
為了進(jìn)行上述測(cè)試,請(qǐng)?zhí)峤粌?nèi)部事務(wù)并回滾外部事務(wù)。
importjava.sql.Connection;publicclassNestedMainimplements Runnable {privateintv = 0;private String name;NestedMain(int v, String name) {this.v = v;this.name = name;}publicstaticvoid main(String[] args) throws Exception{for (inti = 0; i< 3; i++) {NestedMain main = newNestedMain(i * 10, "Ravi" + i);new Thread(main).start();}}@Overridepublicvoid run() {try {TransactionManagerThreadLocal local = newTransactionManagerThreadLocal();// Transaction 1 ( outer )local.beginTransaction();Connection con = local.getConnection();String sql = "INSERT INTO test_tran (emp_id, name) VALUES ('1"+v+"', '"+ name+v+"')";this.insert(con, sql);// Transaction 2 ( Inner )local.beginTransaction();con = local.getConnection();sql = "INSERT INTO test_tran (emp_id, name) VALUES ('2"+v+"', '"+ name+v+"')";this.insert(con, sql);local.commit(); // Committing 2local.rollback(); // Rollback 1 Outer} catch (Exception e) {e.printStackTrace();}結(jié)果
com.ttit.TransactionManagerThreadLocal$1@1270b73--Thread Local Initialize-- com.ttit.TransactionManagerThreadLocal$1@1270b73--Thread Local Initialize-- com.ttit.TransactionManagerThreadLocal$1@1270b73--Thread Local Initialize-- com.mysql.jdbc.JDBC4Connection@10dd1f7--Conection--- com.mysql.jdbc.JDBC4Connection@1813fac--Conection--- com.mysql.jdbc.JDBC4Connection@136228--Conection--- com.mysql.jdbc.JDBC4Connection@1855af5--Conection--- com.mysql.jdbc.JDBC4Connection@e39a3e--Conection--- com.mysql.jdbc.JDBC4Connection@1855af5--Commit--- com.mysql.jdbc.JDBC4Connection@e39a3e--Commit--- com.mysql.jdbc.JDBC4Connection@9fbe93--Conection--- com.mysql.jdbc.JDBC4Connection@9fbe93--Commit--- com.mysql.jdbc.JDBC4Connection@10dd1f7--Rollback--- com.mysql.jdbc.JDBC4Connection@1813fac--Rollback--- com.mysql.jdbc.JDBC4Connection@136228--Rollback---| 拉維220 | 220 |
| 拉維00 | 20 |
| 拉維110 | 210 |
回滾內(nèi)部事務(wù)并提交外部事務(wù)時(shí):
com.ttit.TransactionManagerThreadLocal$1@1270b73--Thread Local Initialize-- com.ttit.TransactionManagerThreadLocal$1@1270b73--Thread Local Initialize-- com.ttit.TransactionManagerThreadLocal$1@1270b73--Thread Local Initialize-- com.mysql.jdbc.JDBC4Connection@9f2a0b--Conection--- com.mysql.jdbc.JDBC4Connection@136228--Conection--- com.mysql.jdbc.JDBC4Connection@1c672d0--Conection--- com.mysql.jdbc.JDBC4Connection@9fbe93--Conection--- com.mysql.jdbc.JDBC4Connection@1858610--Conection--- com.mysql.jdbc.JDBC4Connection@9fbe93--Rollback--- com.mysql.jdbc.JDBC4Connection@1858610--Rollback--- com.mysql.jdbc.JDBC4Connection@1a5ab41--Conection--- com.mysql.jdbc.JDBC4Connection@1a5ab41--Rollback--- com.mysql.jdbc.JDBC4Connection@9f2a0b--Commit--- com.mysql.jdbc.JDBC4Connection@136228--Commit--- com.mysql.jdbc.JDBC4Connection@1c672d0--Commit---| 拉維00 | 10 |
| 拉維220 | 120 |
| 拉維110 | 110 |
資源:
- 了解ThreadLocal背后的概念
翻譯自: https://www.javacodegeeks.com/2013/12/java-nested-transaction-using-threadlocal-in-pojo.html
總結(jié)
以上是生活随笔為你收集整理的在POJO中使用ThreadLocal的Java嵌套事务的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 网址公安备案号在哪里备案(网址公安备案)
- 下一篇: 华理健康安卓(健康 安卓)