精华内容
下载资源
问答
  • mysql中的事务提交

    千次阅读 2018-12-25 23:23:18
    今天被问到了一个mysql自动事务提交的问题,就着这个问题对mysql的事务提交机制进行了一些研究,将测试的结果总结下。 一.mysql的自动事务提交设置 mysql中的自动事务提交是通过参数autocommit配置的,系统默认...

    今天被问到了一个mysql自动事务提交的问题,就着这个问题对mysql的事务提交机制进行了一些研究,将测试的结果总结下。

    一.mysql的自动事务提交设置

    mysql中的自动事务提交是通过参数autocommit配置的,系统默认设置值为1,即开启状态

    如果要关闭事务自动提交,执行下述SQL语句:

    set autocommit=0;

    二.各个事务提交状态与显式事务提交的关系

    以student表为例说明,建表语句如下:

    CREATE TABLE `student` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(255) DEFAULT NULL,
      `age` int(11) DEFAULT NULL,
      `clazz_id` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`)
    )

    1.在autocommit=0,即自动事务提交状态关闭的情况下,必须要执行commit语句,更新才做才会保存到数据库;

    如果sql语句如下:

    set autocommit=0;#关闭事务的自动提交
    insert into student(name,age,clazz_id) values('zhangsan',28,3);

    则执行上述的语句后,查询数据库,发现并没有姓名为zhangsan的记录,说明insert操作并没有保存到数据库。需要执行commit才会真正保存到数据库。

    set autocommit=0;#关闭事务的自动提交
    insert into student(name,age,clazz_id) values('zhangsan',28,3);
    commit;

    执行上面的sql后,查询数据库可以查询到zhangsan的记录,执行commit操作后,insert操作才保存到数据库。

    对于多条insert的操作:

    set autocommit=0;#关闭事务的自动提交
    insert into student(name,age,clazz_id) values('lisi',28,3);
    insert into student(name,age,clazz_id) values('wangwu',28,4);
    commit;

    数据库也可以查询出记录,没有begin语句,只有commit语句,这里的多条insert是不是为同一个事务有待考察。

    2.在autocommit=1,即自动事务提交状态为开启的情况下,不执行commit语句,更改也会保存到数据库,并且各条更改操作是独立的事务,而不是同一个事务。

    set autocommit=1;#开启事务自动提交
    insert into student(name,age,clazz_id) values('zhaoliu',28,3);

    执行上述sql后,查询数据库zaholiu的记录已经存在,说明开启自动事务提交情况下,不显式执行commit提交,mysql也会隐式的帮我们提交事务。

    set autocommit=1;#开启事务自动提交
    insert into student(name,age,clazz_id) values('tianqi',28,4);
    insert into student(name,age,clazz_id) values('wangba',28,3);

    执行语句中有多个更新操作时,上述的两个insert操作是两个独立的事务,即当第一条insert语句成功,第二条insert语句执行失败的情况下,第一条sql语句不会回滚,数据库中可以查询到tianqi的记录。

    到这里总结一:在没有begin,即没有手动开启事务的情况下,autocommit=0时,commit手动提交才会保存到数据库;autocommit=1时,数据库会自动的将更新保存到数据库。

    3.考虑手动开启事务的情况,即出现begin的情况

    autocommit=0的情况

    set autocommit=0;#关闭事务的自动提交
    begin;
    insert into student(name,age,clazz_id) values('lili',28,3);

    执行后数据库查询不到lili记录,手动开启事务后,不执行commit更改不会保存到数据库

    set autocommit=0;#关闭事务的自动提交
    begin;
    insert into student(name,age,clazz_id) values('lili',28,3);
    commit;

    数据库查询到lili记录,说明autocommit=0情况下,有begin必须有commit才会提交。

    autocommit=1的情况

    set autocommit=1;#开启事务自动提交
    begin;
    insert into student(name,age,clazz_id) values('jia',28,4);

    数据库查询不到记录,手动开启事务后,不执行commit更改不会保存到数据库。

    set autocommit=1;#开启事务自动提交
    begin;
    insert into student(name,age,clazz_id) values('jia',28,4);
    commit;

    数据库可以查询到记录,autocommit=1情况下,也要commit才会保存到数据库

    总结第二点:在手动开启事务的情况下(即出现begin),不论自动提交状态是关闭还是打开,都需要commit提交更改才会保存到数据库。

    参考:https://blog.csdn.net/jeaforea/article/details/51994636

    展开全文
  • mysql事务提交

    2014-05-29 17:42:20
    5.3.1事务提交流程 MySQL的事务提交逻辑主要在函数ha_commit_trans中完成。事务的提交涉及到binlog及具体的存储的引擎的事务提交。所以MySQL用2PC来保证的事务的完整性。MySQL的2PC过程如下: (1)先调用...
    5.3.1事务提交流程

    MySQL的事务提交逻辑主要在函数ha_commit_trans中完成。事务的提交涉及到binlog及具体的存储的引擎的事务提交。所以MySQL用2PC来保证的事务的完整性。MySQL的2PC过程如下:

    clip_image002

    (1)先调用binglog_hton和innobase_hton的prepare方法完成第一阶段,binlog_hton的papare方法实际上什么也没做,innodb的prepare将事务状态设为TRX_PREPARED,并将redo log刷磁盘 (innobase_xa_prepare à trx_prepare_for_mysql à trx_prepare_off_kernel)。

    (2)如果事务涉及的所有存储引擎的prepare都执行成功,则调用TC_LOG_BINLOG::log_xid将SQL语句写到binlog,此时,事务已经铁定要提交了。否则,调用ha_rollback_trans回滚事务,而SQL语句实际上也不会写到binlog。

    (3)最后,调用引擎的commit完成事务的提交。实际上binlog_hton->commit什么也不会做(因为(2)已经将binlog写入磁盘),innobase_hton->commit则清除undo信息,刷redo日志,将事务设为TRX_NOT_STARTED状态(innobase_commit à innobase_commit_low à trx_commit_for_mysql à trx_commit_off_kernel)。

    //ha_innodb.cc

    static

    int

    innobase_commit(

    /*============*/

    /* out: 0 */

    THD* thd, /* in: MySQL thread handle of the user for whom

    the transaction should be committed */

    bool all) /* in: TRUE - commit transaction

    FALSE - the current SQL statement ended */

    {

    ...

    trx->mysql_log_file_name = mysql_bin_log.get_log_fname();

    trx->mysql_log_offset =

    (ib_longlong)mysql_bin_log.get_log_file()->pos_in_file;

    ...

    }

    函数innobase_commit提交事务,先得到当前的binlog的位置,然后再写入事务系统PAGE(trx_commit_off_kernel à trx_sys_update_mysql_binlog_offset)。

    InnoDB将MySQL binlog的位置记录到trx system header中:

    //trx0sys.h

    /* The offset of the MySQL binlog offset info in the trx system header */

    #define TRX_SYS_MYSQL_LOG_INFO (UNIV_PAGE_SIZE - 1000)

    #define TRX_SYS_MYSQL_LOG_MAGIC_N_FLD 0 /* magic number which shows

    if we have valid data in the

    MySQL binlog info; the value

    is ..._MAGIC_N if yes */

    #define TRX_SYS_MYSQL_LOG_OFFSET_HIGH 4 /* high 4 bytes of the offset

    within that file */

    #define TRX_SYS_MYSQL_LOG_OFFSET_LOW 8 /* low 4 bytes of the offset

    within that file */

    #define TRX_SYS_MYSQL_LOG_NAME 12 /* MySQL log file name */

    5.3.2 事务恢复流程

    Innodb在恢复的时候,不同状态的事务,会进行不同的处理(见trx_rollback_or_clean_all_without_sess函数):

    <1>对于TRX_COMMITTED_IN_MEMORY的事务,清除回滚段,然后将事务设为TRX_NOT_STARTED;

    <2>对于TRX_NOT_STARTED的事务,表示事务已经提交,跳过;

    <3>对于TRX_PREPARED的事务,要根据binlog来决定事务的命运,暂时跳过;

    <4>对于TRX_ACTIVE的事务,回滚。

    MySQL在打开binlog时,会检查binlog的状态(TC_LOG_BINLOG::open)。如果binlog没有正常关闭(LOG_EVENT_BINLOG_IN_USE_F为1),则进行恢复操作,基本流程如下:

    clip_image004

    <1>扫描binlog,读取XID_EVENT事务,得到所有已经提交的XA事务列表(实际上事务在innodb可能处于prepare或者commit);

    <2>对每个XA事务,调用handlerton::recover,检查存储引擎是否存在处于prepare状态的该事务(见innobase_xa_recover),也就是检查该XA事务在存储引擎中的状态;

    <3>如果存在处于prepare状态的该XA事务,则调用handlerton::commit_by_xid提交事务;

    <4>否则,调用handlerton::rollback_by_xid回滚XA事务。

    5.3.3 几个参数讨论

    (1)sync_binlog

    Mysql在提交事务时调用MYSQL_LOG::write完成写binlog,并根据sync_binlog决定是否进行刷盘。默认值是0,即不刷盘,从而把控制权让给OS。如果设为1,则每次提交事务,就会进行一次刷盘;这对性能有影响(5.6已经支持binlog group),所以很多人将其设置为100。

    bool MYSQL_LOG::flush_and_sync()

    {

    int err=0, fd=log_file.file;

    safe_mutex_assert_owner(&LOCK_log);

    if (flush_io_cache(&log_file))

    return 1;

    if (++sync_binlog_counter >= sync_binlog_period && sync_binlog_period)

    {

    sync_binlog_counter= 0;

    err=my_sync(fd, MYF(MY_WME));

    }

    return err;

    }

    (2) innodb_flush_log_at_trx_commit

    该参数控制innodb在提交事务时刷redo log的行为。默认值为1,即每次提交事务,都进行刷盘操作。为了降低对性能的影响,在很多生产环境设置为2,甚至0。

    clip_image006

    If the value of innodb_flush_log_at_trx_commit is 0, the log buffer is written out to the log file once per second and the flush to disk operation is performed on the log file, but nothing is done at a transaction commit. When the value is 1 (the default), the log buffer is written out to the log file at each transaction commit and the flush to disk operation is performed on the log file. When the value is 2, the log buffer is written out to the file at each commit, but the flush to disk operation is not performed on it. However, the flushing on the log file takes place once per second also when the value is 2. Note that the once-per-second flushing is not 100% guaranteed to happen every second, due to process scheduling issues.

    The default value of 1 is required for full ACID compliance. You can achieve better performance by setting the value different from 1, but then you can lose up to one second worth of transactions in a crash. With a value of 0, any mysqld process crash can erase the last second of transactions. With a value of 2, only an operating system crash or a power outage can erase the last second of transactions.

    (3) innodb_support_xa

    用于控制innodb是否支持XA事务的2PC,默认是TRUE。如果关闭,则innodb在prepare阶段就什么也不做;这可能会导致binlog的顺序与innodb提交的顺序不一致(比如A事务比B事务先写binlog,但是在innodb内部却可能A事务比B事务后提交),这会导致在恢复或者slave产生不同的数据。

    int

    innobase_xa_prepare(

    /*================*/

    /* out: 0 or error number */

    THD* thd, /* in: handle to the MySQL thread of the user

    whose XA transaction should be prepared */

    bool all) /* in: TRUE - commit transaction

    FALSE - the current SQL statement ended */

    {

    if (!thd->variables.innodb_support_xa) {

    return(0);

    }

    5.3.4 安全性/性能讨论

    上面3个参数不同的值会带来不同的效果。三者都设置为1(TRUE),数据才能真正安全。sync_binlog非1,可能导致binlog丢失(OS挂掉),从而与innodb层面的数据不一致。innodb_flush_log_at_trx_commit非1,可能会导致innodb层面的数据丢失(OS挂掉),从而与binlog不一致。

    关于性能分析,可以参考

    http://www.mysqlperformanceblog.com/2011/03/02/what-is-innodb_support_xa/

    http://www.mysqlperformanceblog.com/2009/01/21/beware-ext3-and-sync-binlog-do-not-play-well-together/

    展开全文
  • Mybatis增删改的事务提交

    千次阅读 2020-10-22 16:29:38
    我们的mysql中,涉及增删改的语句都要提交事务,不然不起作用,下面我们就讲讲mybaits中的事务提交 问题展示 我们的插入语句的单元测试没有提交事务,导致数据没有插到数据库 手动提交事务:sqlSession...

    问题展示

    手动提交事务:sqlSession.commit();

    自动提交:sqlSessionFactory.openSession(true);


     

    我们的mysql中,涉及增删改的语句都要提交事务,不然不起作用,下面我们就讲讲mybaits中的事务提交

    问题展示

    我们的插入语句的单元测试没有提交事务,导致数据没有插到数据库

    手动提交事务:sqlSession.commit();

    手动提交需要每个需要提交事务的地方,都要手动写一遍

    自动提交:sqlSessionFactory.openSession(true);

    先看源码

     

    原来我们的

     

    现在修改为自动提交事务

    事务提交成功 

     

    展开全文
  • Java-SpringMVC事务提交

    千次阅读 2017-11-08 13:46:11
    Java-SpringMVC事务提交
    1.方法级事务提交:在方法名上面加入如下代码:
    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    
      示例如下图所示:
               
      在AppContext.xml加入如下配置文件:
    <!-- 配置事务管理器 -->
       <bean id="transactionManager"
    	class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    	   <property name="dataSource" ref="dataSource" />
    	<!-- -->
    	   <property name="nestedTransactionAllowed" value="true"></property>
       </bean>
    	<tx:annotation-driven transaction-manager="transactionManager"
    		proxy-target-class="true" />
    
    2.代码级事务提交:当部分代码需要进行手动提交时,在方法里面加入如下代码:
    DefaultTransactionDefinition def = new DefaultTransactionDefinition();
      def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);// 事物隔离级别,开启新事务
      TransactionStatus status = txManager.getTransaction(def);// 获得事务状态
      try {
       //逻辑代码,可以写上你的逻辑处理代码
       txManager.commit(status);
      } catch (Exception e) {
       txManager.rollback(status);
      }
    
      示例如下图所示:
     
      在AppContext.xml加入如下配置文件:
    xmlns:p="http://www.springframework.org/schema/p" 
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource"/>


    展开全文
  • spring事务提交前后操作

    千次阅读 2019-03-08 17:39:17
    希望在spring 事务提交后对缓存操作,如果提交失败就不要提交缓存 //这个放在事务方法操作中 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() { @Override ...
  • Mybatis的事务提交方式

    2020-05-29 19:35:39
    setAutoCommit()方法来设置事务提交方式的。 这是我们的 Connection 的整个变化过程,通过分析我们能够发现之前的 CUD 操作过程中,我们都要手动进 行事务的提交(session.commit()),原因是 setAutoCommit()...
  • mysql 事务提交过程

    千次阅读 2018-05-23 19:07:55
    打开binlog选项后,执行事务提交命令时,就会进入两阶段提交模式。两阶段提交分为prepare阶段和commit两个阶段。流程如下 :这里面涉及到两个重要的参数:innodb_flush_log_at_trx_commit和sync_binlog,参数可以...
  • sql 事务提交和回滚_SQL提交和回滚

    千次阅读 2020-07-07 07:24:52
    sql 事务提交和回滚The most important aspect of a database is the ability to store data and the ability to manipulate data. COMMIT and ROLLBACKare two such keywords which are used in order store and ...
  • Mysql 事务提交过程

    千次阅读 2017-02-06 17:00:09
    在执行delete或update操作时,实际旧记录没有真正删除,只是在记录上打了一个标记,而是在事务提交后,purge线程真正删除,释放物理页空间。因此,提交过程中会将undo信息加入purge列表,供purge线程处理。 释放锁...
  • Mysql事务提交方式

    千次阅读 2015-08-24 17:55:06
    Mysql有两种事务提交方式:  1:自动提交(默认)  MySQL 在自动提交模式下,每个 SQL 语句都是一个独立的事务。这意味着,
  • spring的异步事务提交

    2019-09-30 11:31:48
    spring的异步事务提交 spring提供便捷的异步日志记录 相信大家在做公司小项目的时候都会遇到,只记录一个或者两个模块的日志记录,如操作记录等 spring中的TransactionSynchronizationManager.registerSynchronization...
  • 理解UNDO-3 事务提交

    千次阅读 2017-03-07 17:55:51
    从前面文章得知,当事务提交后会在数据块中的ITL该XID 标帜字段FLAG 打上C,并在SCN/FCN字段上打上自己提交的SCN.如果说当一个事务更新了1万个块,更新时间比如说30分钟. 这个时候会因为DBWR把被更新的数据块写回磁盘...
  • 数据正确性无法保证:如果异步操作需要反查数据库上一步入库的结果,而上一步的事务由于数据库压力或IO等原因导致事务提交延迟,这时异步操作去数据库里查询数据就会失败; 解决方案: 这就要求我们保证事务...
  • sql事务提交回滚命令 提交,回滚和保存点SQL命令 (Commit, Rollback and Savepoint SQL commands) Transaction Control Language(TCL) commands are used to manage transactions in the database. These are used...
  • spring中事务提交后再发MQ消息

    千次阅读 2020-09-15 12:28:35
    本篇博文记录一个小的知识点,在spring框架下的业务代码中同时有数据库操作,有MQ消息发送,怎么控制消息发送在事务提交之后,有问题可及时在本博客下留言,或者在个人博客留言 业务场景: 在一个加了事务的service...
  • MySQL事务提交过程(二)

    千次阅读 2017-01-01 21:18:45
    上一篇文章我们介绍了在关闭binlog的情况下,事务提交的大概流程。之所以关闭binlog,是因为开启binlog后事务提交流程会变成两阶段提交,这里的两阶段提交并不涉及分布式事务,当然mysql把它称之为内部xa事务...
  • 1.Hibernate事务隔离等级设置: 一般情况下载属性文件中设置: hibernate.connection.isolation=4等号后面的数字表示意思如下: ...2.事务提交: Session session = HibernateUtil.getSession();//HibernateUtil
  • @Transactional事务提交后执行异步任务

    千次阅读 2020-08-28 11:39:21
    1. @Transactional事务提交后执行异步任务 2. 我们先看一段代码, 问题:我们在发送消息时如果事务未提交,此时异步方法中的select(id)方法是查询不到数据的 @Transactional(rollbackFor = Exception.class) ...
  • InnoDB---深入理解事务提交--01

    千次阅读 2016-12-31 20:58:19
    ...当事务正常执行结束时,事务的提交操作,是实现事务原子性的主要操作...如下我们重点分析事务提交过程中一些重要环节。   一 事务提交的整体过程  InnoDB和MySQL Server联合实现了事务的提交全程
  • 手动事务提交

    2019-12-02 17:09:54
    我们现在进行事务控制一般都是使用注解型事务,然而有些时候却会发现注解型事务失效了。比如下方的这种情况: @Transactional(propagation= Propagation.REQUIRES_NEW,rollbackFor = Exception.class) @Override ...
  • SQL 事务提交

    千次阅读 2017-01-05 23:20:26
    事务的状态:活动状态(初始状态),部分提交状态(事务执行完最后一条语句,实际输出可能临时驻留在内存中),提交状态(当数据库系统将事务中对数据的梗概完全写入磁盘时,写入事务日子一条信息),失败状态(事务...
  • jdbc事务提交

    2017-06-08 10:06:11
    若想关闭这种默认提交方式,让多条SQL在一个事务中执行,并且保证这些语句是在同一时间共同执行的时,我们就应该为这多条语句定义一个事务。  其中,银行转账这一事例,最能说明,使用事务的重要性了。  update ...
  • MySQL作为一种关系型数据库,已被广泛应用到互联网中的诸多项目中。...由于mysql插件式存储架构,导致开启binlog后,事务提交实质是二阶段提交,通过两阶段提交,来保证存储引擎和二进制日志的一致。
  • 事务提交5000条update,耗时:13.79 秒,内存占用:17.88 MB(大量时间消耗在Query生成sql语句上) $startTime = microtime(true); $startMemory = memory_get_usage(); $transaction = \Yii::$app->db->begin...
  • Hibernate的事务提交

    千次阅读 2012-08-04 20:53:22
    转帖Fromhttp://blog.csdn.net/noove_001/archive/2007/10/26/... 这是在一次事务提交时遇到的异常。  an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use
  • sqlserver事务提交

    千次阅读 2016-05-13 10:13:59
    sqlserver在默认情况下,事务是自动提交的,即进行delete等操作的时候,是不需要显式commit的,那么,如何设置为显式提交呢? 1.将语句写到显式写到事务中 begin tran delete t1 rollback tran/commit tran 2.设置...
  • spring应用中事务提交后执行某方法

    千次阅读 2019-05-29 13:58:14
    * 事务提交之后发送kafka消息 * 不在事务控制中的,切勿调用此方法 */ private void send(String message) { TransactionSynchronizationManager.registerSynchronization(new ...
  • Spring+Mybatis嵌套事务,在子事务提交后查数据为空 需求场景 public class BServiceImpl implements BSevice{ @Autowired private ASevice aSevice; @Resource(name="transactionManager") ...
  • 之前说到缓存的管理问题,具体看redis缓存管理问题,我想要实现缓存的逻辑在事务提交之后,考虑使用事务监听器,这个我之前也用过,使用监听器实现在事务提交后发送消息,那么问题是我如何拦截到注解,然后发出事件...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 35,893
精华内容 14,357
关键字:

事务提交