日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

在POJO中使用ThreadLocal的Java嵌套事务

發(fā)布時(shí)間:2023/12/3 java 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在POJO中使用ThreadLocal的Java嵌套事务 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

大多數(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ù)無關(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ù)管理器類,如下所示:

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來維護(hù)每個(gè)事務(wù)的連接:

public void beginTransaction()

開始事務(wù)以開始新的事務(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類將為單線程創(chuàng)建嵌套事務(wù)。

多線程的嵌套事務(wù)

對(duì)于多線程應(yīng)用程序,每個(gè)線程都有獨(dú)立的事務(wù)和嵌套事務(wù)。

我們提出使用ThreadLocal來管理連接棧。

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--- 名稱 emp_id
拉維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--- 名稱 emp_id
拉維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ǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。