实战项目中:一个业务对多个数据库操作的同步的处理办法(要么都成功,要么都失败)Thread。。。
实战项⽬中:⼀个业务对多个数据库操作的同步的处理办法(要么都成功,要么都失败)Thread。。。
事务:⼀个数据库的操作就是⼀个事务。
简单的事务:对⼀个表进⾏增删改查。
默认数据库的事务在Dao层,⾃动开始、⾃动提交、⾃动回滚(insert、update、delete)。
当业务复杂的情况下:
添加报销单(需要添加⼀个报销单信息记录----报销单信息表,多个报销项⽬的记录----报销单项⽬表,当报销单信息表添加成功,多个报销单记录也必须添加到另⼀张表中。如果这其中有⼀条记录出现了问题,所有的数据都不应该添加到数据库中)致富种植
银⾏转账(转账表中⼀个⽤户的转账记录,进账表中⼀个⽤户的进账记录,当⼀个⽤户转账成功的同时,另⼀个⽤户也必须同时进账,如果两⽅中的某⼀⽅进账失败或者转账失败,则整个的记录都失败作废)
所以我们需要将事务设置为⼿动提交,就银⾏转账的情况来说,转账的时候开始启动,确定转账成功之后提交所有数据写⼊数据库,如果这其中⼀⽅出现了问题,那么就回滚,恢复于原始状态(并不是指数据库,⽽是指数据库缓存)
下⾯我们⽤代码来实现这个情况:(两个数据表,必须要⽤⼀个Connection,所以在数据库增删改查的时候不能关闭connection,最后在service中统⼀关闭)
1:⾸先我们需要在操作两张表之前提前获取⼀个Connection,并且引⼊新的知识点:ThreadLocal,需要新建⼀个ThreadLocal对
象,ThreadLocal⾥存⼊⼀个Connecction,如果是第⼀次执⾏,ThreadLocal⾥没有Connection,这个时候我们需要新建⼀个Connection,将这个Connection存进ThreadLocal中去。
1. private static ThreadLocal<Connection>threadLocal=new ThreadLocal<>();
2.    private DBUtil2(){
3.
4.    }
5.
镇定的近义词和反义词6.    /**
7.      * 获取数据库连接
8.      * @return
9.      */
教师节画画图片大全10.    public static  Connection getConnection(){
11.        Connection ();
12.        if(conn==null){
13.            String driver = "sql.jdbc.Driver";
14.            String url = "jdbc:mysql://127.0.0.1:3306/sxtoa";// ip  port  dbname
15.            String user = "root";
世界之最大全16.            String password = "root";
17.            try {
18.                //加载驱动
19.                Class.forName(driver);
20.                //建⽴和数据库的连接
21.                conn = Connection(url,user,password);
22.            } catch (ClassNotFoundException e) {
23.                e.printStackTrace();
24.            } catch (SQLException e) {
25.                e.printStackTrace();
26.            }
27.            threadLocal.set(conn);
28.        }
29.        return conn;
30.    }
然后在业务层执⾏两张表的操作之前,提前获取到这同⼀个连接,并且设置⾃动提交的属性为false,如果两张表的数据操作成功了就把这个数据提交了,如果失败了,就会抛出异常,那咱们就在catch⾥进⾏事务回滚,⼀切回到从来没有添加过的状态,数据库缓存恢复成原来的状态即可,如果成功了,两张表的数据就都添加成功
1.  public void add(Expense expense) {
2.        //统⼀的获得连接,全局只让有⼀个连接,只要有⼀个失败,就全部回滚
3.        Connection conn= Connection();
4.        //这⾥加try catch就是为了能够让异常丢出去,然后来判断是否添加成功
5.        try {
世界之最大全6.            conn.setAutoCommit(false);
7.            //先添加报销数据,这⾥要如何返回⼀个expId呢?select @@identity返回最近添加的第⼏列
8.            int expId = expenseDao.add(expense);
9.            //提取报销项⽬
10.            List<ExpenseItem> ItemList = ExpenseItemList();
11.            for (int i = 0; i < ItemList.size(); i++) {
12.                ExpenseItem item = (i);
13.                item.setExpId(expId);
14.                //添加报销项⽬数据
15.                expenseItem.add(item);
止咳
16.            }
17.            connmit();
18.        }catch (Exception e){
19.            e.printStackTrace();
20.            try {
21.                //事务回滚
22.                llback();
23.            } catch (SQLException e1) {
24.                e1.printStackTrace();
25.                throw new Message());
26.            }
27.            throw new Message());
28.        }
29.    }

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。