background

Some time ago, when I looked at the project code, I found that the process of some interfaces was quite long. In each service, database transactions were used to ensure the consistency of data, but the consistency was not guaranteed in the upstream controller layer.

I have checked online, but have not found a mature distributed transaction framework based on Go open source.

Tcc-transaction is a distributed transaction framework based on TCC ideas.

TCC codes Try, Confirm, and Cancel, respectively.

Try: Attempts to execute services

Complete all service checks (Consistency) Reserve required service resources (quasi-isolation)Copy the code

Confirm: Indicates that the service is executed

Services are executed without any service check. Only Confirm operations reserved for the Try phase are used to meet the idempotency requirementCopy the code

Cancel: Cancels the service

The Cancel operation to release service resources reserved during the Try phase is idempotentCopy the code

To understand how it works, the first step is to run through the code in the tCC-Transaction-tutorial-sample section that comes with the project.

Today I will focus on the various pits encountered in the process of running through TCC-Transaction-tutorial-sample.

Depend on the environment

  • Java
  • Maven
  • Git
  • MySQL
  • Redis
  • Zookeeper
  • Intellij IDEA

Source code address: github.com/changmingxi…

I Fork one myself (configuration changes have been committed) : github.com/DMinerJacki…

Hit the pit course

Hit the pit to prepare

Step 1: Clone the code

Git clone github.com/DMinerJacki… Command download code

Step 2: Import the code and execute the database script

Code import Intellij IDEA.

Perform TCC ws-transaction – HTTP – sample/SRC/main/dbscripts database scripts.

Step 3: Modify the configuration file

The main modification is the database configuration parameters. Take tCC-transaction-Dubbo-sample as an example. The following files need to be modified

tcc-transaction/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-capital/src/main/reso urces/tccjdbc.properties

tcc-transaction/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-redpacket/src/main/re sources/tccjdbc.properties

tcc-transaction/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-dubbo-order/src/main/resour ces/tccjdbc.properties

The configuration of the three files is as follows

Use driver names based on the specific MySQL version
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
Change the address to which you connect to the databaseTCC. JDBC. Url = JDBC: mysql: / / 127.0.0.1:3306 / TCC? useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false
Change the username you need to configure the database
jdbc.username=root
Change the password you need to configure the database
jdbc.password=rootroot

c3p0.initialPoolSize=10
c3p0.minPoolSize=10
c3p0.maxPoolSize=30
c3p0.acquireIncrement=3
c3p0.maxIdleTime=1800
c3p0.checkoutTimeout=30000
Copy the code

Modify the jdbc.proerties file data in tCC-transaction-sample-capital, TCC-transaction-sample-redpacket, and TCC-transaction-sample-order at the same time Library connection, modified configuration as follows

JDBC. DriverClassName = com. Mysql, JDBC Driver. JDBC url = JDBC: mysql: / / 127.0.0.1:3306 / TCC_CAP? useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=falseTCC. JDBC. Url = JDBC: mysql: / / 127.0.0.1:3306 / TCC? useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false
jdbc.username=root
jdbc.password=rootroot

c3p0.initialPoolSize=10
c3p0.minPoolSize=10
c3p0.maxPoolSize=30
c3p0.acquireIncrement=3
c3p0.maxIdleTime=1800
c3p0.checkoutTimeout=30000
Copy the code

Step 4: Start the project

Based on the project’s readme.md file and the online articles, we know that to get through the sample project, we need to start three projects separately.

Tcc-transaction is available in two versions:

  • Sample version based on Dubbo communication

  • Sample version of HTTP-based communication

The three projects for which the two versions correspond are

  • Tcc-transaction-dubo-capital (account asset service), tcc-transaction-dubo-redpacket (redpacket service), tcc-transaction-dubo-order (transaction order service)

  • Tcc-transaction-http-capital (account asset service), tcc-transaction-http-redpacket (redpacket service), tcc-transaction-http-order (transaction order service)

I actually ran both versions, and the only one that succeeded was the Dubbo communication-based sample version (the HTTP version failed most at the final confirm, resulting in the order status being Unkown).

Take the example of dubbo based communication

The startup configuration of TCC-Transaction-Dubbo-Capital is as follows

The startup configuration of TCC-transaction-Dubo-Redpacket is as follows

The startup configuration of TCC-transaction-Dubbo-order is as follows

Pit 1: zK cannot be connected

The tCC-Transaction-Dubbo-capital project is started, and the following error message is reported

[sample-dubbo-capital]2019-08-31 17:48:05.312 INFO  [org.apache.zookeeper.ZooKeeper] Initiating client connection, connectString=127.00.1:2181 sessionTimeout=30000 watcher=org.I0Itec.zkclient.ZkClient@32c7bb63
[sample-dubbo-capital]2019-08-31 17:48:05.334 INFO  [org.apache.zookeeper.ClientCnxn] Opening socket connection to server 127.00.1 /.127.00.1:2181. Will not attempt to authenticate using SASL (unknown error)[sample - dubbo - capital] 2019-08-31 17:48:05, WARN 344 [org. Apache. The zookeeper. ClientCnxn] Session 0 x0for server null, unexpected error, closing socket connection and attempting reconnect
java.net.ConnectException: Connection refused
	at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
	at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:717)
	at org.apache.zookeeper.ClientCnxnSocketNIO.doTransport(ClientCnxnSocketNIO.java:361)
	at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1081)[sample - dubbo - capital] 2019-08-31 17:48:06, 456 INFO/org. Apache. Zookeeper. ClientCnxn Opening the socket connection to the server 127.0.0.1/127.0.0.1:2181 Will not attempt to authenticate usingSASL (unknown error)[sample - dubbo - capital] 2019-08-31 17:48:06, WARN 459 [org. Apache. The zookeeper. ClientCnxn] Session 0 x0for server null, unexpected error, closing socket connection and attempting reconnect
java.net.ConnectException: Connection refused
	at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
	at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:717)
	at org.apache.zookeeper.ClientCnxnSocketNIO.doTransport(ClientCnxnSocketNIO.java:361)
	at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1081)[sample - dubbo - capital] 2019-08-31 17:48:07, 566 INFO/org. Apache. Zookeeper. ClientCnxn Opening the socket connection to the server 127.0.0.1/127.0.0.1:2181 Will not attempt to authenticate usingSASL (unknown error)[sample - dubbo - capital] 2019-08-31 17:48:07, WARN 567 [org. Apache. The zookeeper. ClientCnxn] Session 0 x0for server null, unexpected error, closing socket connection and attempting reconnect
java.net.ConnectException: Connection refused
Copy the code

From the error message, it is obvious that zK, or ZooKeeper, cannot be connected.

This makes sense because ZK is not installed locally, so install and start ZK with “./ zkserver. sh start”

Pit 2: Redis can’t connect

Tcc-transaction-dubo-order:

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.mengyun.tcctransaction.sample.dubbo.order.service.PlaceOrderServiceImpl org.mengyun.tcctransaction.sample.dubbo.order.web.controller.OrderController.placeOrderService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'placeOrderServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.mengyun.tcctransaction.sample.dubbo.order.service.PaymentServiceImpl org.mengyun.tcctransaction.sample.dubbo.order.service.PlaceOrderServiceImpl.paymentService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'paymentServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.mengyun.tcctransaction.sample.dubbo.capital.api.CapitalTradeOrderService org.mengyun.tcctransaction.sample.dubbo.order.service.PaymentServiceImpl.capitalTradeOrderService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'captialTradeOrderService': Post-processing of FactoryBean's singleton object failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'compensableTransactionAspect' defined in class path resource [tcc-transaction.xml]: Cannot resolve reference to bean 'transactionConfigurator' while setting bean property 'transactionConfigurator'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionConfigurator': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.mengyun.tcctransaction.TransactionRepository org.mengyun.tcctransaction.spring.support.SpringTransactionConfigurator.transactionRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionRepository' defined in file [/Users/jackie/workspace/tcc-transaction/tcc-transaction-tutorial-sample/tcc-transaction-dubbo-sample/tcc-transaction-du Bbo - order/target/TCC ws-transaction - dubbo - order - 1.2.6 / WEB - INF/classes/config/spring/local/appcontext - service - TCC. XML] : Error setting property values; nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are: PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'jedisPool' threw exception; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(Autowired AnnotationBeanPostProcessor.java:526) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnn otationBeanPostProcessor.java:295) ... 60 moreCopy the code

This is similar to the above reason. There is no redis installed locally, so we cannot get the Redis connection.

So install Redis and start Redis with “redis-server”.

Pit 3: Cause: org. Springframework. JDBC. CannotGetJdbcConnectionException: Could not get JDBC Connection

After all three projects are started, you can see a list page of product links, but you can’t jump after clicking the links, and the following error is reported

Type Exception Report
Message Request processing failed; nested exception is org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException:
Description The server encountered an unexpected condition that prevented it from fulfilling the request.
Exception
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: An attempt by a client to checkout a Connection has timed out.
### The error may exist in URL [jar:file:/Users/jackie/workspace/tcc-transaction/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transa Ction - HTTP - order/target/TCC ws-transaction - HTTP - order - 1.2.6 / WEB - INF/lib/TCC ws-transaction - sample - order - 1.2.6. Jar! /config/sqlmap/main/sample-product.xml]
### The error may involve org.mengyun.tcctransaction.sample.order.infrastructure.dao.ProductDao.findByShopId
### The error occurred while executing a query
### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: An attempt by a client to checkout a Connection has timed out.
	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:965)
	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:844)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
	org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
	org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:106)

Root Cause
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: An attempt by a client to checkout a Connection has timed out.
### The error may exist in URL [jar:file:/Users/jackie/workspace/tcc-transaction/tcc-transaction-tutorial-sample/tcc-transaction-http-sample/tcc-transa Ction - HTTP - order/target/TCC ws-transaction - HTTP - order - 1.2.6 / WEB - INF/lib/TCC ws-transaction - sample - order - 1.2.6. Jar! /config/sqlmap/main/sample-product.xml]
Copy the code

According to the error information, the MySQL version does not match the database driver version.

The local MySQL version is “8.0.11 MySQL Community Server-gpl “, but the corresponding driver version in TCC-Transaction is

< the dependency > < groupId > mysql < / groupId > < artifactId > mysql connector - Java < / artifactId > < version > 5.1.33 < / version > </dependency>Copy the code

Instead of

< the dependency > < groupId > mysql < / groupId > < artifactId > mysql connector - Java < / artifactId > < version > 8.0.11 < / version > </dependency>Copy the code

For older versions, useSSL=false is required after the jdbC-URL of the connection

Pit 4: Loading class ‘com.mysql.jdbc.driver ‘. This is deprecated

Loading class ‘com.mysql.jdbc.driver ‘. This is deprecated” Loading class’ com.mysql.jdbc.driver ‘.

Driver’ is deprecated. Com.mysql.cj.jdbc.driver is required. Therefore, modify jdbc.proerties configuration (see above for details).

After stepping on the pit above, the three projects are started to complete the process and realize a commodity purchase behavior based on distributed transaction. The specific process is shown in the figure below

conclusion

Running the sample project does not go smoothly for a few reasons

  • The local environment configuration is inconsistent with that provided by the project, leading to many detours, such as the MySQL version.
  • Detailed documentation of running sample projects is missing.
  • The information available online is sketchy and old, and the instructions for the steps that work are no longer applicable to current code.

So, after so many potholes, avoid the same detour.

Welcome to JackieZheng