开发者社区> 问答> 正文

JDBC事务为TRANSACTION_REPEATABLE_READ,但是无效:报错

Jfinal中设置了JDBC事务为TRANSACTION_REPEATABLE_READ,但是无效:报错

我在JFinal2.2上测试并发程序:

思路是并发的读取数据库中的一个int字段然后对它进行加1操作

数据表:

CREATE TABLE `unsafe_test` (
  `id` int(11) NOT NULL,
  `number` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


首先我设置了JDBC的事务级别


arp.setTransactionLevel(Connection.TRANSACTION_REPEATABLE_READ);


然后在controller中写一个方法


public void readAndWrite() {
    // 先读取一个值,再写入数据库
    UnsafeTest t = UnsafeTest.dao.findById(1);
    System.out.println("id: " + Thread.currentThread().getId() + " number: " + t.getNumber());
    t.setNumber(t.getNumber() + 1);
    t.update();
    renderText("OK");
}
结果打印的结果是:


id: 130 number: 1
id: 128 number: 1
id: 147 number: 1
id: 91 number: 1
id: 34 number: 1
id: 149 number: 1
id: 111 number: 1
id: 148 number: 1
id: 35 number: 1
id: 35 number: 2

出现了重复读取,请问向这种情况是JDBC的事务级别配置的问题,还是代码的问题?




展开
收起
kun坤 2020-06-14 13:38:31 968 0
1 条回答
写回答
取消 提交回答
  • TRANSACTION_SERIALIZABLE######   事务在哪打开的?没到看 @Before(Tx.class) ,也没看到 Db.tx(...),建议详细看一下 jfinal 手册有关事务的用法,在此下载: http://www.jfinal.com######

    引用来自“JFinal”的评论

       事务在哪打开的?没到看 @Before(Tx.class) ,也没看到 Db.tx(...),建议详细看一下 jfinal 手册有关事务的用法,在此下载: http://www.jfinal.com
    我讲代码用Db包裹起来后
    public void readAndWrite() {
    Db.tx(new IAtom() {
    @Override
    public boolean run() throws SQLException {
    UnsafeTest t = UnsafeTest.dao.findById(1);
    System.out.println("id: " + Thread.currentThread().getId() + " number: " + t.getNumber());
    t.setNumber(t.getNumber() + 1);
    return t.update();
    }
    });
    renderText("OK");
    }


    打印输出:
    id: 121 number: 0
    id: 117 number: 0
    id: 108 number: 0
    id: 105 number: 0
    id: 112 number: 1
    id: 122 number: 1
    id: 119 number: 1
    id: 110 number: 1
    id: 121 number: 2
    id: 106 number: 2
    仍然出现了~重复读,不解
    ######直接使用 Db.update("update unsafe_test set number=number+1 where id=?", id);######

    引用来自“dy810810”的评论

    TRANSACTION_SERIALIZABLE

    不行。。当我设置这个最高事务级别时

    直接抛出异常:

    com.jfinal.plugin.activerecord.ActiveRecordException: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction

    ######多线程死锁了,但会保障事务安全
    2020-06-14 13:38:36
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载