spring 多執行緒事務的問題
阿新 • • 發佈:2019-02-12
Java程式碼
- @Service
- public class ServiceA {
- @Transactional
- public void threadMethod(){
- this.insert();
- System.out.println("main insert is over");
- for(int a=0 ;a<3;a++){
- ThreadOperation threadOperation= new ThreadOperation();
-
Thread innerThread = new
- innerThread.start();
- }
- }
- public class ThreadOperation implements Runnable {
- public ThreadOperation(){
- }
- @Override
- public void run(){
- insert();
-
System.out.println("thread insert is over"
- }
- }
- public void insert(){
- //do insert......
- }
- }
如果吧上面insert方法提出到新的類中,加入事務註解,就能成功的把insert方法加入到事務管理當中
Java程式碼- @Service
- public class ServiceA {
- @Autowired
- private ServiceB serviceB;
- @Transactional
- public void threadMethod(){
-
this
- System.out.println("main insert is over");
- for(int a=0 ;a<3;a++){
- ThreadOperation threadOperation= new ThreadOperation();
- Thread innerThread = new Thread(threadOperation);
- innerThread.start();
- }
- }
- public class ThreadOperation implements Runnable {
- public ThreadOperation(){
- }
- @Override
- public void run(){
- serviceB.insert();
- System.out.println("thread insert is over");
- }
- }
- public void insert(){
- //do insert......
- }
- }
- @Service
- public class ServiceB {
- @Transactional
- public void insert(){
- //do insert......
- }
- }
另外,使用多執行緒事務的情況下,進行回滾,比較麻煩。
thread的run方法,有個特別之處,它不會丟擲異常,但異常會導致執行緒終止執行。
最麻煩的是,線上程中丟擲的異常即使在主執行緒中使用try...catch也無法截獲
這非常糟糕,我們必須要“感知”到異常的發生。比如某個執行緒在處理重要的事務,當thread異常終止,我必須要收到異常的報告,才能回滾事務。
這時可以使用執行緒的UncaughtExceptionHandler進行異常處理,UncaughtExceptionHandler名字意味著處理未捕獲的異常。更明確的說,它處理未捕獲的執行時異常
如下程式碼
執行緒出要使用
①處要丟擲異常
②處要捕捉異常,並且要丟擲RuntimeException
③處手動處理回滾邏輯
Java程式碼- @Service
- public class ServiceA {
- @Autowired
- private ServiceB serviceB;
- @Transactional
- public void threadMethod(){
- this.insert();
- System.out.println("main insert is over");
- for(int a=0 ;a<3;a++){
- ThreadOperation threadOperation= new ThreadOperation();
- Thread innerThread = new Thread(threadOperation);
- innerThread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
- public void uncaughtException(Thread t, Throwable e) {
- try {
- serviceB.delete();③
- } catch (Exception e1) {
- e1.printStackTrace();
- }
- }
- });
- innerThread.start();
- }
- }
- public class ThreadOperation implements Runnable {
- public ThreadOperation(){
- }
- @Override
- public void run(){
- try {
- serviceB.insert();
- }catch (Exception ex){ ②
- System.out.println(" Exception in run ");
- throw new RuntimeException();
- }
- System.out.println("thread insert is over");
- }
- }
- public void insert(){
- //do insert......
- }
- }
- @Service
- public class ServiceB {
- @Transactional
- public void insert() throws Exception{ ①
- //do insert......
- }
- @Transactional
- public void delete() throws Exception{
- //do delete......
- }
- }