当前位置:网站首页>I'm almost addicted to it. I can't sleep! Let a bug fuck me twice!
I'm almost addicted to it. I can't sleep! Let a bug fuck me twice!
2022-06-28 10:00:00 【Little brother Fu】
author : Little brother Fu
Blog :https://bugstack.cn
precipitation 、 Share 、 grow up , Let yourself and others have something to gain !
One 、 Preface : One Bug
I didn't expect one Bug, I was fucked twice !
I'm probably addicted , I can't sleep , Sit up and open Mac And external display , this Bug There is no reason , Silently looking at the screen with abnormal printing , One is mine , The other one is also mine .
Recently, it may be the volume source code , I'm addicted to cigarettes . First, 《 Handwriting Spring》, Then the 《 Handwriting Mybatis》, But I didn't expect a small problem to make me 2 Time !
Today, this question is mainly reflected in the common Mybatis, When inserting data , We can return the returned value of the library table index through the input parameter object . But through my own handwriting Mybatis, Every time I come back 0, Instead of finally inserting the index value of the library table . Because it's handwritten , Not directly Mybatis, So I will start from the file parsing 、 Object mapping 、SQL Query for 、 The packaging of the results has been checked , But the problem is not here ?!

- This is this. selectKey Configuration of , In the execution of the insert SQL after , Start to get the last index value .
- Usually as long as the configuration is OK , The return object also has a corresponding id Field , Then you can get the return value correctly .PS: Here's the problem , Written by little brother fu Mybatis It turns out that only one 0!
Two 、 analysis : Abnormal diagnosis
Most of the R & D partners may not have read Mybatis Source code , So it's probably not clear what's going on here , Little brother Fu, draw a picture for you , Tell you what happened so that the result returned is 0 Of .

Mybatis The process of processing can be divided into two parts , One part is parsing , The other part is to use . When parsing, put Mapper XML Medium insert Label statements are parsed out , At the same time, analyze selectKey label . After the final parsing , Use the parsed statement information MappedStatement The mapping statement class is stored . Convenient for follow-up in DefaultSqlSession When performing an operation , It can be downloaded from Configuration It is obtained from the configuration item for use .
So here is a very important point , Is to perform insert When inserting , It also contains a query operation . That means , We'll be at once Insert in , Contains two execution statements . a key :bug It happened here , Why? ? Because when these two statements are executed at the beginning , When getting links , Each one is to get a new link , So in other words ,insert xxx、select LAST_INSERT_ID() In two connection During connection execution , It's not true , Unable to get the inserted index ID, Only under a link or a transaction ( once commit) Can have the characteristics of transaction , Get the auto increment after inserting data ID.
And because this part was written at the beginning JdbcTransaction Realization Transaction When the interface gets the connection , Every time it's a new link , The code block is as follows ;

- Here's a link to get , At the beginning, there was no if null The judgment of the , Every time I get the link directly , So this is not a link under the two SQL operation , So we will not get the right result , It is equivalent to just executing alone
SELECT LAST_INSERT_ID()So the final query result is 0 When it's over ! You can test copying this statement to SQL Query tool
- Here's a link to get , At the beginning, there was no if null The judgment of the , Every time I get the link directly , So this is not a link under the two SQL operation , So we will not get the right result , It is equivalent to just executing alone
3、 ... and 、 shock : The same pit
But in fact, there is such a link problem , Write in little brother Fu's handwriting Spring Also encountered in .

stay Spring There is a part about transaction processing , In fact, the operation of these transactions is also correct JDBC Packaging operations for , Rely on the links obtained from the data source to manage transactions . And we usually use Spring It is also combined with Mybatis Configure the data source , Then operate multiple transactions under one transaction SQL At the time of statement , How to get the same link . Because from the above case , We know the characteristics of guaranteed transactions , Need to be under the same link , Even if there are multiple operations SQL
Due to the multiple SQL The operation of , It is equivalent to getting a new one every time Session There is a new link from the connection pool , But in order to achieve the characteristics of transactions , Therefore, multiple transactions are required SQL The transaction operation needs to be started before , Whether it's manual or annotation .
The transaction start action processing makes some restrictions on transaction propagation behavior and isolation level , In fact, the more important thing is to make multiple SQL The execution of get the link , The need is the same . So here we introduce ThreadLocal Based on the synchronization feature that it saves information under the same thread operation , In fact, the link obtained from the transaction here , In fact, it is saved to TransactionSynchronizationManager#resources Attribute .
Although it's just a small piece of content , But at the beginning of little brother Fu's handwriting Spring When , It was also left out . Until the time of the test , The link discovery transaction is always unsuccessful , At first, I thought that the whole facet logic was not cut in or my operation mode was wrong . Until the debugging code is checked step by step , It is found that there are many SQL The execution of is not the same link obtained , So there is no way to make the transaction effective .
Four 、 common : Transaction failure
It may be such a small link problem , Sometimes it will cause a lot of exceptions , If we haven't learned the source code , Then you may not know how such a problem happened . Therefore, they often conduct in-depth research and exploration , So that you can explain a problem , It's simpler and more direct .
So you say , What are the reasons for transaction invalidation ?- Share some common , If you encounter other , You can send it to the comment area to have a look .
- The database engine does not support transactions : Here we use MySQL For example , Its MyISAM The engine does not support transaction operations ,InnoDB It's the engine that supports transactions , Generally, support transactions will use InnoDB.https://dev.mysql.com/doc/refman/8.0/en/storage-en… from MySQL 5.5.5 The default storage engine to start with is :InnoDB, Before the default is :MyISAM, So it's worth noting , The underlying engine doesn't support transactions. No matter what happens, it's just a waste of time .
- The method is not public Of : come from Spring Official documents 【When using proxies, you should apply the @Transactional annotation only to methods with public visibility. If you do annotate protected, private or package-visible methods with the @Transactional annotation, no error is raised, but the annotated method does not exhibit the configured transactional settings. Consider the use of AspectJ (see below) if you need to annotate non-public methods.】@Transactional It can only be used for public On the way , Otherwise, the transaction will not fail , If it is to be used in non public On the way , Can be opened AspectJ The proxy pattern .
- Has not been Spring management :
// @Service - It is commented out here public class OrderServiceImpl implements OrderService { @Transactional public void placeOrder(Order order) { // ... } } - The data source is not configured with transaction manager : Generally, it comes from the self-developed database routing component
@Bean public PlatformTransactionManager transactionManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } - Abnormally swallowed .catch Then I ate it directly , Transaction exception cannot be rolled back . At the same time, configure the corresponding exception
@Transactional(rollbackFor = Exception.class)
5、 ... and 、 summary : Learning experience
Many technical problems like this , It all comes from little brother Fu's study of the source code , The first thing is to look at the source code when you encounter problems , Although it is often difficult to smooth out the whole logic , However, a little bit of accumulation will indeed enable R & D personnel to have a more solid understanding of Technology .
So the reason why I write now Spring、 Handwriting Mybatis, I also hope to sort out all such knowledge , Learn the design scheme of complex logic from it 、 Design principles and how to use design patterns to solve the problems of complex scenes .PS: Usually our business code complexity is difficult to reach this level , So I have seen ” God “ after , In the future, it will be easy to design the business undertaken .
The other is to control all kinds of technical details , And accumulated in this experience to apply relevant technical design to some similar SpringBoot Starter Development, etc , Only such breadth 、 Height 、 depth , Can we really improve our R & D ability .PS: It is also to go further on the road of technology , Whether it's advanced development 、 Architects 、CTO!
边栏推荐
- Data visualization makes correlation analysis easier to use
- PMP考试重点总结四——规划过程组(2)
- Proxy mode (proxy)
- R language plot visualization: plot to visualize overlapping histograms, and use geom at the bottom edge of the histogram_ The rugfunction adds marginal rugplots
- Matplotlib属性及注解
- Unity loads AssetBundle resources from the server and writes them to local memory, and loads the downloaded and saved AB resources from local memory to the scene
- Explain final, finally, and finalize
- Application of X6 in data stack index management
- 学习机器学习的最佳路径是什么
- Django数据库操作以及问题解决
猜你喜欢

通过PyTorch构建的LeNet-5网络对手写数字进行训练和识别

增强 Jupyter Notebook 的功能,这里有四个妙招

Dolphin scheduler uses system time

Caffeine cache, the king of cache, has stronger performance than guava

为什么 Istio 要使用 SPIRE 做身份认证?

Linux下安装redis 、Windows下安装redis(超详细图文教程)
![QT signal and slot communication mechanism (when multiple windows communicate back and forth [parent and child windows])](/img/17/57ffb7393b71eddc5ac92ae3944338.jpg)
QT signal and slot communication mechanism (when multiple windows communicate back and forth [parent and child windows])

适配器模式(Adapter)

PMP考试重点总结五——执行过程组

Key summary V of PMP examination - execution process group
随机推荐
HDI blind hole design, have you noticed this detail?
股票开户用中金证券经理发的开户二维码安全吗?知道的给说一下吧
PMP考试重点总结七——监控过程组(1)
小米旗下支付公司被罚 12 万,涉违规开立支付账户等:雷军为法定代表人,产品包括 MIUI 钱包 App
桥接模式(Bridge)
在OpenCloudOS使用snap安装.NET 6
RESTful风格
bad zipfile offset (local header sig)
云服务器MYSQL查询速度慢
栈的弹出压入序列<难度系数>
mysql打不开,闪退
Google开源依赖注入框架-Guice指南
Summary of MySQL basic knowledge points
The R language uses the avplots function in the car package to create added variable plots. In image interaction, manually identify (add) strong influence points that have a great impact on each predi
MySQL基础知识点总结
卸载oracle报错
MySQL的开发环境和测试环境有什么区别??
Custom exception classes and exercises
再見!IE瀏覽器,這條路由Edge替IE繼續走下去
R语言使用car包中的avPlots函数创建变量添加图(Added-variable plots)、在图像交互中,在变量添加图中手动标识(添加)对于每一个预测变量影响较大的强影响点