Transaction of spring's reactive / imperative relational database

Jiedao jdon 2021-05-03 16:58:34
transaction spring reactive imperative relational

Spring Framework Recently it was announced that Support for reactive transaction management . Let's take a closer look at this for R2DBC(SQL Database access response specification ) How it works .

Transaction management is a model , Not technology specific . From this point of view , Its properties and runtime behavior are a function of the implementation technology .

From a database perspective , Imperative and responsive transactions work in the same way . from Java From the perspective of , There are some differences between mandatory and passive transactions .

Let's start with imperative trading .

Imperative Trading

In imperative transactions , More specifically, aspect oriented transaction management , For example, interceptors , Transaction state is usually transparent to code . The bottom layer is based on API, We can get transaction state and transaction binding resources from somewhere . This place usually exists in ThreadLocal In storage . Imperative transactions assume that all the transactional work of your code is the same Thread.

Another aspect of command transactions is in @Transactional Keep all context data in the method while the transaction is in progress , image JPA Such a tool allows you to go through Java 8 Carry out the results Stream. Streaming , in any case , Streaming requires a closed @Transactional Method . When a transaction is in progress , Data in any transaction does not leave the scope of the method .

I point out these two problems because they behave differently in reactive transactions .

Resource binding

Before proceeding with reactive transactions , We need to improve our understanding of transaction state . Transaction state usually includes transaction state ( Started , Has been submitted , Rolled back ) And the corresponding resource bound to the transaction .

Transactional resources ( For example, database connections ) Usually its transaction process is bound to the underlying transport connection . in the majority of cases , This is a TCP Connect . In the case of a database connection using multiplexing , State is bound to the session object . In rare cases , Database operations accept transaction or session identifiers . therefore , We assume that , We bind the connection to the transaction to include the lowest capability method , Because transaction state usually cannot be migrated across connections .

Reactive business

When using reactive programming , We want to use transactions with the same convenience as traditional applications ( Using the same programming model ), Again, use annotation based @Transactional The method of transaction annotation of . Back to the idea that transaction management is just a pattern , The only thing we need to change is technology .

The reaction transaction no longer binds its transaction state ThreadLocal, It's bound to the subscriber context . This is the context associated with a particular execution path . Or to put it another way : Each response sequence implemented gets a subscriber context isolated from other execution . This is already the first difference in mandatory matters .

The second difference is from @Transactional Data escaped from the method . Use Reactive Streams Reactive programming is almost all through the function of reactive operators for data flow and data flow transmission . And asynchronous API comparison , It's also a major advantage ,Publisher The publisher just needs to get the decoding of the database driver , The first element is emitted , Not in Future Wait for the last packet to arrive before completion .

Reactive transactions contain this fact : Similar to imperative transactions , The transaction starts before it actually works . When we generate data from transactional work , The data flow will flow through the publisher when the transaction is active Publisher. That means the data has escaped @Transactional The way to mark . We will realize that @Transactional Methods are just markers in the reaction sequence , We don't focus on the inside of the method ;  We'd rather just look at the impact of subscription and completion .

If any errors occur during the transaction , We may leave behind the data that was processed in the transaction when the transaction was rolled back . This is something your application needs to consider . Reactive transaction management as intended does not delay the launch , Streaming properties are not ignored . Atomic weight ratio flows in applications ​​ It's much heavier , So you can handle this in your application .


from Java Point of view , Use R2DBC Reactive database access is completely non blocking . all I / O All use non blocking sockets . So from R2DBC Get is I / O It will no longer block your threads . however , Reactive relational database driver conforms to database communication protocol and database behavior . Although we no longer need to block a thread , But we're still using the database connection , Because this is RDBMS How it works - Send command by command . Some databases allow a little optimization , It's called pipelining . In pipeline mode , The driver keeps sending commands to the connection , Without waiting for the last command to complete .

Usually , You can release the connection if :

  1. Statement ( Multiple statements ) Completed
  2. Application transaction completed

We can still observe the lock that blocks the connection .

The database lock

According to the database you use , You can observe MVCC Behavior or blocking behavior , This is usually a transaction lock . For imperative SQL Database transactions , We usually end up with two (b) lock :

  • Application threads are I / O prevent
  • The database holds a lock

Our application only works when the database releases the lock . Releasing the lock also unblocks the application thread . Due to non blocking I / O, Using reactive database integration no longer clogs application threads . Database lock behavior still exists . We end up using blocked database connections , But it won't stop two resources ( The other is application threads ).

from Java From the perspective of ,TCP The connection is cheap .

because SQL How databases work , We still have a strong guarantee of consistency

ACID Standard database

SQL There are three perspectives on database and passive response :

  • lock : When we talk about reactions ,SQL Databases are not the best persistence mechanism . Many databases perform internal locking while running updates , So concurrent access is limited . Some database applications MVCC, Allow progress , Locking has less impact . In any case , Heavily used use cases may not be suitable for your reactive application , Because for the traditional SQL database , This can create scalability bottlenecks .
  • Scalability :SQL Databases are usually better than NoSQL Worse , You can place it again 50 Expand your cluster with two computers . Use something like RedShift,CockroachDB,Yugabyte Such a new SQL database , We can expand in different ways , And more than the traditional SQL The database is better .
  • The cursor : many SQL Database has response function in its wired protocol . This is usually similar to chunked fetching. When you run a query , The reaction driver can read the cursor results by getting a small number of results , So as not to crush the driver . Once the first line is read , The driver can then send the line down to its consumer and proceed to the next line . After processing the block , The driver can start processing the next block . If the subscription is cancelled , The driver will stop reading from the cursor and release it . It's a very powerful design .

Is there really any performance advantage ?

You don't choose reactive for throughput , Just for scalability . Some of the impacts will affect throughput based entirely on back pressure . Back pressure is Subscriber The concept of how many items a subscriber can handle at a time .

When the current data is processed , Imperative drivers usually get the next block of data . Plug the driver's underlying connections and threads , Until the database replies ( Imperative acquisition model , The white area between requests is delay ).

In terms of resource use , Reactive drivers don't block threads . To make a long story short , They have in the process of materialization GC Friendly execution model . During stream generation ,GC Pressure will increase .


You've learned about imperative and reactive database properties . Transaction management needs to be implemented in imperative flow in a different way than reactive code . The changes in the implementation reflect slightly different runtime behavior , Especially when it comes to data escape . By changing performance profiles for latency and resource usage , You can get the same strong consistency guarantee .

本文为[Jiedao jdon]所创,转载请带上原文链接,感谢

  1. 浅谈 React 中的 XSS 攻击
  2. XSS attack in react
  3. 自学前端教程整理,附不容错过的前端100篇文章合集
  4. Self taught front-end tutorial collation, with a collection of 100 front-end articles that can not be missed
  5. 使用OpenTracing跟踪Go中的HTTP请求延迟
  6. Using opentracing to track HTTP request latency in go
  7. Encapsulating databinding allows you to write less than 10000 lines of code
  8. 03-HTML5标签-HTML5极速入门
  9. 03-html5 tag-html5 quick start
  10. LayUI - 极易上手拿来即用的前端 UI 框架
  11. Layui - easy to use front end UI framework
  12. Interpretation of lodash source code (1)
  13. Why is the first parameter of node family callback error?
  14. 报告:JavaScript 开发者达1380 万,C#超越 PHP,Rust 增长最快
  15. Report: Javascript developers reach 13.8 million, C surpasses PHP, and rust grows fastest
  16. 小白前端入门笔记(10),怎么设置网站内部的超链接?
  17. How to set up hyperlinks inside the website?
  18. Using node and socket to realize online chat room
  19. The core competitiveness of Vue: data bidirectional binding
  20. React configuration agent
  21. CSS layout
  22. Application scenario explanation of Vue dynamic component
  23. Redux learning notes 04 -- using multiple reducers to manage data
  24. After three months of typescript writing, what have I learned?
  25. Node family - what is a callback?
  26. React -- a simple implementation of render & create element
  27. JS learning simple usage of jquery
  28. Seamless love
  29. 小白前端入门笔记(12),设置哑链接
  30. Small white front-end entry notes (12), set dumb links
  31. Vue2. X opens composition API and TSX
  32. Interview record and thinking of social recruitment for one and a half years (Alibaba, Tencent, baidu offer)
  33. Flex learning notes
  34. The most essential closure article in the eastern hemisphere
  35. 2021-05-03 hot news
  36. Sword finger offer -- reverse order pair in array (JS Implementation)
  37. Working process of scaffold
  38. Use decorator mode to strengthen your fetch
  39. [JS] scope (Introduction)
  40. Employment information statistics network (interface document)
  41. Analysis of MVC
  42. [middle stage] please stay and join me in the backstage
  43. Understanding front end garbage collection
  44. [continuous update] front end special style implementation
  45. Flutter product analysis and package reduction scheme
  46. XPath positioning
  47. 前端开发css中的flex布局的使用
  48. The use of flex layout in front end development CSS
  49. JQuery核心函数和静态方法
  50. JQuery core functions and static methods
  51. Node family - understanding of blocking and non blocking
  52. 热点微前端Microfrontend的讨论:谷歌AdWords是真实的微前端
  53. Vue source code analysis (2) initproxy initialization proxy
  54. What's TM called react diff
  55. Summary of common front end data structure
  56. Useeffect in hooks
  57. [encapsulation 02 design pattern] Command pattern, share meta pattern, combination pattern, proxy pattern, strategy pattern
  58. Front end notes: virtual Dom and diff of vue2. X
  59. The best code scanning plug-in of flutter
  60. The simplest plug-in for rights management of flutter