java如何在保证事务同时回滚的情况下读未提交?

发布于 2022-09-11 19:58:56 字数 130 浏览 20 评论 0

问题是这样的,先更新一个实体数据,再根据其ID反查数据库查询更新后的数据,组装另一类实体数据保存
想把 更新和新增操作放在同一事务里以达到任一出错就回滚的目的,但是这样一来如何在新增时读到更新数据?此时因为更新和新增处于同一事务,还未提交。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

§对你不离不弃 2022-09-18 19:58:56

保证不了,常用做法是加一个version或者update timestamp,entity每次更新都会更新version或者timestamp。如果事物查询后得到的数据,做更新,发现version或者timestamp与读取时不同,就抛出异常,回滚事务。

东风软 2022-09-18 19:58:56

在同一个事物中,更新后(事务未提交)再查询也是可以查询到更新后的数据,所以你的这个过程是可以的,是有数据库保证的。

举个例子吧:


   package com.lz.dao.base;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;


public class Test {
    
   public static void main(String[] args){
       execute();
   }
   
   /**
    * 使用的数据库为mysql,数据库默认隔离级别为:repeatable
    * 下面的代码只为演示用
    */
   public static void execute(){
       Connection con = null;
       try{
            con = DbUtils.getConnection();
            con.setAutoCommit(false);
               String updateSql = "update lz_nav_category set name = 'google' where id = 55";//更新分类名称
               PreparedStatement ps = con.prepareStatement(updateSql);
               ps.executeUpdate();
               
               String querySql = "select name from lz_nav_category where id = 55";//查询新分类名称,是可以查到的。
               
               PreparedStatement ps2 = con.prepareStatement(querySql);
               ResultSet set = ps2.executeQuery();
               String newName = "";
               if(set.next()){
                   newName = set.getString(1);
               }
               String insertSql = "INSERT INTO `lz`.`lz_nav` (`nav_name`, `nav_desc`) VALUES (?,?)";//用上面查询的新的名字组织数据,插入记录
               PreparedStatement ps3 = con.prepareStatement(insertSql);
               ps3.setString(1, newName);
               ps3.setString(2, "描述");
               ps3.executeUpdate();
               con.commit();       //提交事务
       }catch(Exception ex){
           DbUtils.rollback(con);//回滚事务
       }finally{
           DbUtils.release(con, null, null);
       }
   }
}

最后结果:
fucj.gif

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文