第一次写博客,还请大家多多支持

今天同事问了个问题:在多个select的时候,用不用放入同一个事务?

首先先看个例子:

publicclassJDBCClient {

publicstaticvoidmain(String[] args) {

Connection conn = null;

try{

Class.forName("com.mysql.jdbc.Driver");

conn = DriverManager.getConnection("jdbc:mysql://localhost/test","root","123456");

if(conn !=null) {

//将本次会话的事务隔离级别设置为TRANSACTION_READ_COMMITTED,mysql默认的是REPEATABLE_READ

conn.setTransactionIsolation(2);

//关闭事务的自动提交

conn.setAutoCommit(false);

PreparedStatement ps = conn.prepareStatement("select student_no from student where student_id = 1 ");

ResultSet rs = ps.executeQuery();

while(rs.next()) {

System.out.println(rs.getString(1));

}

//设置断点,并将数据库中执行 update student set student_no = '新的值' where student_id = 1;然后继续执行

System.out.println("-----------");

rs = ps.executeQuery();

while(rs.next()) {

//这里打印出新赋值的值

System.out.println(rs.getString(1));

}

//提交事务

//conn.commit();

}

} catch(Exception e) {

e.printStackTrace();

if(conn !=null) {

try{

conn.rollback();

} catch(SQLException e1) {

e1.printStackTrace();

}

}

}

}

//注:如果应用mysql默认的事务隔离级别,则两次打印出的内容一致;

}public class JDBCClient {

public static void main(String[] args) {

Connection conn = null;

try {

Class.forName("com.mysql.jdbc.Driver");

conn = DriverManager.getConnection("jdbc:mysql://localhost/test","root","123456");

if(conn != null) {

//将本次会话的事务隔离级别设置为TRANSACTION_READ_COMMITTED,mysql默认的是REPEATABLE_READ

conn.setTransactionIsolation(2);

//关闭事务的自动提交

conn.setAutoCommit(false);

PreparedStatement ps = conn.prepareStatement("select student_no from student where student_id = 1 ");

ResultSet rs = ps.executeQuery();

while(rs.next()) {

System.out.println(rs.getString(1));

}

//设置断点,并将数据库中执行 update student set student_no = '新的值' where student_id = 1;然后继续执行

System.out.println("-----------");

rs = ps.executeQuery();

while(rs.next()) {

//这里打印出新赋值的值

System.out.println(rs.getString(1));

}

//提交事务

//conn.commit();

}

} catch (Exception e) {

e.printStackTrace();

if(conn != null) {

try {

conn.rollback();

} catch (SQLException e1) {

e1.printStackTrace();

}

}

}

}

//注:如果应用mysql默认的事务隔离级别,则两次打印出的内容一致;

}

个人觉得多个select时,不用放入一个事务,select查询本身不需要事务提交。而如果在修改数据时,不提交事务,则会修改失败。

select只是用来进行查询操作,不需要事务回滚,因为select不会对数据库的产生持久化的修改,没有必要在数据发生不一致的时候进行回滚。如果要防止数据的不一致情况,可以通过修改事务的隔离级别实现。

事务:

事务的四大特性 (ACID)

1、原子性(Atomicity) 事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

2、一致性(Consistency)事务前后数据的完整性必须保持一致。

3、隔离性(Isolation)多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间的数据要相互隔离。

4、持久性(Durability)一个事务一旦被提交,它对数据库中的数据改变就是永久性的。

事务的隔离级别:

多个线程开启各自的事务操作数据库中数据时,数据库系统要负责隔离操作,以保证各个线程在获取数据时的准确性。也就是说,隔离级别就是对对事务并发控制的等级。如果事务不考虑隔离性会引发以下问题:

(1)脏读:

指一个事务读取了另外一个事务未提交的数据。比如 A 向 B 购买商品,如果 B 的事务隔离级别为最低的 read uncommitted,那么当 A 执行了 update account set money=money+100 where name='B';以后并没有提交数据的时候,B 进行了 select money from account where name='B';查询账户的操作,由于 B 的事务隔离级别最低,所以导致了脏读,读取到了

A 没有提交的数据,当 A 执行了 rollback 回滚命令以后,B 再查询账户,就发现先前增加的 100 元消失了。为了避免脏读,我们可以将事务的隔离级别设置为:read committed。

(2)不可重复读:

在一个事务内读取到了表中的某一行数据,多次读取结果不同。不可重复读和脏读的区别是:脏读是读取前一事务未提交的数据,不可重复读是重新读取了前一个事务已提交的数据。比如还是刚才的情景,当 B 将自己的事务隔离级别设置了 read committed 时,可以避免脏读,也就是别人没有提交的数据是读不到的。但是如果 A 将数据提交了,执行了 commit 命令后,B 在这个当前事务内再次查询账户的时候,就发现账户多了 100 元,这种情况看似是符合逻辑的,但是我们这里说到的不可重复读是指在这个当前事务内,不可以发生两次读取操作结果不一致的可能性,我们要保证在一个事务中,我们多次从数据库获取的数据应该是一致的,这样才能保证我们进行数据操作的可靠性。为了避免这个为题,我们可以将数据库的事务隔离级别设置为:repeatable

read,这样就保证了在一个事务中,每次读取到数据都是一致的。

(3)虚读 ( 幻读 )

在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。和不可重复读的区别是:不可重复读是读取到了别人对表中的某一条记录进行了修改,导致前后读取的数据不一致。  虚读是前后读取到表中的记录总数不一样,读取到了其它事务插入的数据。比如现在有 A 和 B 两个应用程序,他们并发访问了数据库中的某一张表,假设表中有 3 条记录,B 执行查询操作, 第一次查询表得到了 3 条记录。此时 A 对表进行了修改,增加了一条记录,当 B 再次查询表的时候,发现多了一条数据。这种情况就造成了 B 的虚读。但是虚读是不一定每次都发生的,这种情况是不确定的。为了避免虚读,我们可以将事务隔离级别设置为

serializable 如果设置成了这种级别,那么数据库就变成了单线程访问的数据库,导致性能降低很多。

四种隔离级别及特点:

隔离级别

是否存在脏读

是否存在不可重复读

是否存在幻读

Read UnCommit(未提交读)

Y

Y

Y

Read Commit(提交读)

N

Y

Y

Repeated Reader(可重复读)

N

N

Y

Serializable Reader(序列化读)

N

N

N

mysql 事务 select_mysql 多个select需要放入一个事务吗?相关推荐

  1. char N2Char(int n)函数:将一个整数转换为字符串,并放入一个字符串中

    //将一个整数转换为字符串,并放入一个字符串中 char N2Char(int n)//一次只能转换一个数 {int i;char c;if ((i = n / 10) != 0)N2Char(i); ...

  2. Flutter一切皆widget但是不要将所有东西放入一个widget

    本文主要介绍Flutter一切皆widget但是不要将所有东西放入一个widget 作为 Flutter 开发人员,我相信您在您的开发生活中至少听说过这句流行的句子:"**一切都是widge ...

  3. 打印1-400以内 能同时被5和9 整数的数将这些数放入一个列表中,再输出这个列表

    import java.util.ArrayList;/*** @author silence* 打印1-400以内 能同时被5和9 整数的数将这些数放入一个列表中,再输出这个列表*/ public ...

  4. 集合练习。学生信息包括学号、姓名、出生日期、性别。把N个学生的信息放入一个集合中。可以根据学号,对学生信息进行检索。并可以根据生日进行排序输出。

    集合练习.学生信息包括学号.姓名.出生日期.性别.把N个学生的信息放入一个集合中.可以根据学号,对学生信息进行检索.并可以根据生日进行排序输出. Student.java package Collec ...

  5. 桌上有一只盘子,每次只能放入一个水果。请用Wait()、Signal()原语实现爸爸、儿子、女儿三个并发进程的同步。

    1.桌上有一只盘子,每次只能放入一个水果.爸爸专向盘中放苹果,妈妈专向盘中放桔子,一个女儿专等吃盘中的苹果,一个儿子专等吃盘中的桔子.试用P,V操作写出他们(4个并发进程)能同步的程序. semaph ...

  6. 设一个学生的信息包括学号、姓名、出生日期和性别等。把n个学生的信息放入一个集合中,可以根据学号对学生信息进行检索,并且可以根据出生日期对学生进行排序输出。

    设一个学生的信息包括学号.姓名.出生日期和性别等.把n个学生的信息放入一个集合中,可以根据学号对学生信息进行检索,并且可以根据出生日期对学生进行排序输出. 要求 对于每个学生的个人信息,可以定义一个类 ...

  7. Spring事务For循环中的代码单独为一个事务,循环一次提交一次事务

    最近业务碰到for循环事务,也就是一个不成功,所有的操作全部回滚.需求做到每个for循环中的代码要单独回滚单独提交,不能影响外部代码环境,研究过之后,记录开发过程 @Transactional(rol ...

  8. mysql 参数 列 排序_将参数放入MySQL IN()后,按降序对列进行排序?

    为此,将FIELD()方法与DESC一起使用.让我们首先创建一个表-mysql> create table DemoTable -> ( -> Number int -> ); ...

  9. linux中如何分割字符串数组中,关于bash:linux shell脚本:拆分字符串,将它们放入一个数组中,然后循环遍历它们...

    本问题已经有最佳答案,请猛点这里访问. Possible Duplicate: Split string based on delimiter in Bash? 在bash脚本中,如何使用像;这样的分 ...

最新文章

  1. 面试前赶紧看了5道Python Web面试题,Python面试题No17
  2. 一次谷歌面试趣事(转)
  3. windows mysql dump_mysql在Windows下使用mysqldump命令手动备份数据库和自动备份数据库...
  4. Flash补间引擎应用:图片特效(2)
  5. 小甲鱼-010-012列表
  6. 好代码是管出来的——.Net Core中的单元测试与代码覆盖率
  7. UCScript——C++集成脚本
  8. 大小端模式的快速判断方法
  9. mysql中定时任务_mysql中定时任务的用法
  10. mysql-5.5.56配置_mysql 5.5.56免安装版配置方法
  11. 【API进阶之路】帮公司省下20万调研费!如何巧用情感分析API实现用户偏好调研
  12. 新手操作孕妇防辐射服暴利项目,也能日入500+
  13. 用canvas代码写或者three.js代码写一张截图,这张截图里面包含4张图片 ,其中3张图片有倾斜立体效果,剩下的一张是背景图...
  14. 矩阵快速幂: 网易2017实习生编程题 魔力手环
  15. 中关村-DIY之国外网盘下载测试
  16. 亿级流量电商详情页系统的大型高并发与高可用缓存架构实战
  17. 【机器人】工业机器人如何赋能3C制造升级?工业机器人的16项重要应用;工业机器人的11个知识问答,“业内人”必看!
  18. [XDOJ] ISBN号码
  19. 常见的MySQL优化方案1
  20. socket简介及java实例

热门文章

  1. 在线重定义生产环境大表分区的惨烈踩雷记录
  2. 一文详解Kafka API
  3. 线程、多线程和线程池,看完这些你就能全部搞懂了
  4. 从零开始学习python | 实例讲解如何制作Python模式程序
  5. 大数据好还是不好_学python好还是大数据好?想学IT,但有点搞不清方向的人可以看看...
  6. c语言程序2048_C语言2048小游戏演示和说明
  7. php 抓取 wordpress 文字内容,如何抓取WordPress文章
  8. 红橙Darren视频笔记 bsdiff bspatch 使用(Linux下)
  9. m1芯片MacBook安装Apple优化版TensorFlow(虚拟环境)
  10. 常用Latex表达式符号——组合数学篇