Full Code of Zh1Cheung/tyloo for AI

master 69c934eb4d6a cached
256 files
431.2 KB
116.0k tokens
844 symbols
1 requests
Download .txt
Showing preview only (529K chars total). Download the full file or copy to clipboard to get everything.
Repository: Zh1Cheung/tyloo
Branch: master
Commit: 69c934eb4d6a
Files: 256
Total size: 431.2 KB

Directory structure:
gitextract_mxpupjhz/

├── .gitignore
├── README.md
├── pom.xml
├── tyloo-api/
│   ├── pom.xml
│   └── src/
│       └── main/
│           └── java/
│               └── io/
│                   └── tyloo/
│                       └── api/
│                           ├── Propagation.java
│                           ├── TransactionContext.java
│                           ├── TransactionContextEditor.java
│                           ├── TransactionStatus.java
│                           ├── TransactionXid.java
│                           ├── Tyloo.java
│                           ├── UniqueIdentity.java
│                           └── UuidUtils.java
├── tyloo-core/
│   ├── pom.xml
│   └── src/
│       └── main/
│           └── java/
│               └── io/
│                   └── tyloo/
│                       ├── CancellingException.java
│                       ├── ConcurrentTransactionException.java
│                       ├── ConfirmingException.java
│                       ├── InvocationContext.java
│                       ├── NoExistedTransactionException.java
│                       ├── OptimisticLockException.java
│                       ├── Participant.java
│                       ├── SystemException.java
│                       ├── Terminator.java
│                       ├── Transaction.java
│                       ├── TransactionManager.java
│                       ├── TransactionRepository.java
│                       ├── common/
│                       │   ├── MethodRole.java
│                       │   └── TransactionType.java
│                       ├── context/
│                       │   └── MethodTransactionContextEditor.java
│                       ├── interceptor/
│                       │   ├── TylooCoordinatorAspect.java
│                       │   ├── TylooCoordinatorInterceptor.java
│                       │   ├── TylooMethodContext.java
│                       │   ├── TylooTransactionAspect.java
│                       │   └── TylooTransactionInterceptor.java
│                       ├── recover/
│                       │   ├── TylooRecoverConfiguration.java
│                       │   └── TylooTransactionRecovery.java
│                       ├── repository/
│                       │   ├── CachableTransactionRepository.java
│                       │   ├── FileSystemTransactionRepository.java
│                       │   ├── JdbcTransactionRepository.java
│                       │   ├── RedisTransactionRepository.java
│                       │   ├── TransactionIOException.java
│                       │   └── helper/
│                       │       ├── ExpandTransactionSerializer.java
│                       │       ├── JedisCallback.java
│                       │       ├── RedisHelper.java
│                       │       └── TransactionSerializer.java
│                       ├── serializer/
│                       │   ├── JacksonJsonSerializer.java
│                       │   ├── JdkSerializationSerializer.java
│                       │   ├── KryoPoolSerializer.java
│                       │   └── ObjectSerializer.java
│                       ├── support/
│                       │   ├── BeanFactory.java
│                       │   ├── FactoryBuilder.java
│                       │   └── TransactionConfigurator.java
│                       └── utils/
│                           ├── ByteUtils.java
│                           ├── CollectionUtils.java
│                           ├── ReflectionUtils.java
│                           ├── StringUtils.java
│                           ├── TransactionUtils.java
│                           └── TylooMethodUtils.java
├── tyloo-dubbo/
│   ├── pom.xml
│   └── src/
│       └── main/
│           ├── java/
│           │   └── io/
│           │       └── tyloo/
│           │           └── dubbo/
│           │               ├── constants/
│           │               │   └── TransactionContextConstants.java
│           │               ├── context/
│           │               │   └── DubboTransactionContextEditor.java
│           │               └── proxy/
│           │                   ├── javassist/
│           │                   │   ├── TylooClassGenerator.java
│           │                   │   ├── TylooJavassistProxyFactory.java
│           │                   │   └── TylooProxy.java
│           │                   └── jdk/
│           │                       ├── MethodProceedingJoinPoint.java
│           │                       ├── TylooInvokerInvocationHandler.java
│           │                       └── TylooJdkProxyFactory.java
│           └── resources/
│               ├── META-INF/
│               │   └── dubbo/
│               │       └── org.apache.dubbo.rpc.ProxyFactory
│               └── tyloo-dubbo.xml
├── tyloo-spring/
│   ├── pom.xml
│   └── src/
│       └── main/
│           ├── dbscripts/
│           │   └── db.sql
│           ├── java/
│           │   └── io/
│           │       └── tyloo/
│           │           └── spring/
│           │               ├── ConfigurableCoordinatorAspect.java
│           │               ├── ConfigurableTransactionAspect.java
│           │               ├── recover/
│           │               │   ├── DefaultTylooRecoverConfiguration.java
│           │               │   └── RecoverScheduledJob.java
│           │               ├── repository/
│           │               │   └── SpringJdbcTransactionRepository.java
│           │               └── support/
│           │                   ├── SpringBeanFactory.java
│           │                   ├── SpringPostProcessor.java
│           │                   └── SpringTransactionConfigurator.java
│           └── resources/
│               └── tyloo.xml
├── tyloo-tutorial-sample/
│   ├── pom.xml
│   ├── src/
│   │   └── tylooSampledb/
│   │       ├── create_db_cap.sql
│   │       ├── create_db_ord.sql
│   │       ├── create_db_red.sql
│   │       └── create_db_tcc.sql
│   ├── tyloo-dubbo-sample/
│   │   ├── pom.xml
│   │   ├── src/
│   │   │   └── main/
│   │   │       └── tylooSampledb/
│   │   │           ├── create_db_cap.sql
│   │   │           ├── create_db_ord.sql
│   │   │           ├── create_db_red.sql
│   │   │           └── create_db_tcc.sql
│   │   ├── tyloo-dubbo-capital/
│   │   │   ├── pom.xml
│   │   │   └── src/
│   │   │       └── main/
│   │   │           ├── java/
│   │   │           │   └── io/
│   │   │           │       └── tyloo/
│   │   │           │           └── sample/
│   │   │           │               └── dubbo/
│   │   │           │                   └── capital/
│   │   │           │                       └── service/
│   │   │           │                           ├── CapitalAccountServiceImpl.java
│   │   │           │                           └── CapitalTradeOrderServiceImpl.java
│   │   │           ├── resources/
│   │   │           │   ├── config/
│   │   │           │   │   └── spring/
│   │   │           │   │       └── local/
│   │   │           │   │           ├── appcontext-service-provider.xml
│   │   │           │   │           ├── appcontext-service-tcc.xml
│   │   │           │   │           └── appcontext-web-servlet.xml
│   │   │           │   ├── log/
│   │   │           │   │   └── log4j.xml
│   │   │           │   ├── sample-dubbo-capital.properties
│   │   │           │   └── tccjdbc.properties
│   │   │           └── webapp/
│   │   │               ├── WEB-INF/
│   │   │               │   └── web.xml
│   │   │               └── index.jsp
│   │   ├── tyloo-dubbo-capital-api/
│   │   │   ├── pom.xml
│   │   │   └── src/
│   │   │       └── main/
│   │   │           └── java/
│   │   │               └── io/
│   │   │                   └── tyloo/
│   │   │                       └── sample/
│   │   │                           └── dubbo/
│   │   │                               └── capital/
│   │   │                                   └── api/
│   │   │                                       ├── CapitalAccountService.java
│   │   │                                       ├── CapitalTradeOrderService.java
│   │   │                                       └── dto/
│   │   │                                           └── CapitalTradeOrderDto.java
│   │   ├── tyloo-dubbo-order/
│   │   │   ├── pom.xml
│   │   │   └── src/
│   │   │       └── main/
│   │   │           ├── java/
│   │   │           │   └── io/
│   │   │           │       └── tyloo/
│   │   │           │           └── sample/
│   │   │           │               └── dubbo/
│   │   │           │                   └── order/
│   │   │           │                       ├── service/
│   │   │           │                       │   ├── AccountServiceImpl.java
│   │   │           │                       │   ├── PaymentServiceImpl.java
│   │   │           │                       │   └── PlaceOrderServiceImpl.java
│   │   │           │                       └── web/
│   │   │           │                           └── controller/
│   │   │           │                               ├── OrderController.java
│   │   │           │                               └── vo/
│   │   │           │                                   └── PlaceOrderRequest.java
│   │   │           ├── resources/
│   │   │           │   ├── config/
│   │   │           │   │   └── spring/
│   │   │           │   │       └── local/
│   │   │           │   │           ├── appcontext-service-dubbo.xml
│   │   │           │   │           ├── appcontext-service-tcc.xml
│   │   │           │   │           └── appcontext-web-servlet.xml
│   │   │           │   ├── log/
│   │   │           │   │   └── log4j.xml
│   │   │           │   ├── sample-dubbo-order.properties
│   │   │           │   └── tccjdbc.properties
│   │   │           └── webapp/
│   │   │               └── WEB-INF/
│   │   │                   ├── ftl/
│   │   │                   │   ├── index.ftl
│   │   │                   │   ├── pay_success.ftl
│   │   │                   │   ├── product_detail.ftl
│   │   │                   │   └── shop.ftl
│   │   │                   └── web.xml
│   │   ├── tyloo-dubbo-redpacket/
│   │   │   ├── pom.xml
│   │   │   └── src/
│   │   │       └── main/
│   │   │           ├── java/
│   │   │           │   └── io/
│   │   │           │       └── tyloo/
│   │   │           │           └── sample/
│   │   │           │               └── dubbo/
│   │   │           │                   └── redpacket/
│   │   │           │                       └── service/
│   │   │           │                           ├── RedPacketAccountServiceImpl.java
│   │   │           │                           └── RedPacketTradeOrderServiceImpl.java
│   │   │           ├── resources/
│   │   │           │   ├── config/
│   │   │           │   │   └── spring/
│   │   │           │   │       └── local/
│   │   │           │   │           ├── appcontext-service-provider.xml
│   │   │           │   │           ├── appcontext-service-tcc.xml
│   │   │           │   │           └── appcontext-web-servlet.xml
│   │   │           │   ├── log/
│   │   │           │   │   └── log4j.xml
│   │   │           │   ├── sample-dubbo-redpacket.properties
│   │   │           │   └── tccjdbc.properties
│   │   │           └── webapp/
│   │   │               ├── WEB-INF/
│   │   │               │   └── web.xml
│   │   │               └── index.jsp
│   │   └── tyloo-dubbo-redpacket-api/
│   │       ├── pom.xml
│   │       └── src/
│   │           └── main/
│   │               └── java/
│   │                   └── io/
│   │                       └── tyloo/
│   │                           └── sample/
│   │                               └── dubbo/
│   │                                   └── redpacket/
│   │                                       └── api/
│   │                                           ├── RedPacketAccountService.java
│   │                                           ├── RedPacketTradeOrderService.java
│   │                                           └── dto/
│   │                                               └── RedPacketTradeOrderDto.java
│   ├── tyloo-http-sample/
│   │   ├── pom.xml
│   │   ├── tyloo-http-capital/
│   │   │   ├── pom.xml
│   │   │   └── src/
│   │   │       └── main/
│   │   │           ├── java/
│   │   │           │   └── io/
│   │   │           │       └── tyloo/
│   │   │           │           └── sample/
│   │   │           │               └── http/
│   │   │           │                   └── capital/
│   │   │           │                       └── service/
│   │   │           │                           ├── CapitalAccountServiceImpl.java
│   │   │           │                           └── CapitalTradeOrderServiceImpl.java
│   │   │           ├── resources/
│   │   │           │   ├── config/
│   │   │           │   │   └── spring/
│   │   │           │   │       └── local/
│   │   │           │   │           ├── appcontext-service-provider.xml
│   │   │           │   │           ├── appcontext-service-tcc.xml
│   │   │           │   │           └── appcontext-web-servlet.xml
│   │   │           │   ├── log/
│   │   │           │   │   └── log4j.xml
│   │   │           │   └── tccjdbc.properties
│   │   │           └── webapp/
│   │   │               ├── WEB-INF/
│   │   │               │   └── web.xml
│   │   │               └── index.jsp
│   │   ├── tyloo-http-capital-api/
│   │   │   ├── pom.xml
│   │   │   └── src/
│   │   │       └── main/
│   │   │           └── java/
│   │   │               └── io/
│   │   │                   └── tyloo/
│   │   │                       └── sample/
│   │   │                           └── http/
│   │   │                               └── capital/
│   │   │                                   └── api/
│   │   │                                       ├── CapitalAccountService.java
│   │   │                                       ├── CapitalTradeOrderService.java
│   │   │                                       └── dto/
│   │   │                                           └── CapitalTradeOrderDto.java
│   │   ├── tyloo-http-order/
│   │   │   ├── pom.xml
│   │   │   └── src/
│   │   │       └── main/
│   │   │           ├── java/
│   │   │           │   └── io/
│   │   │           │       └── tyloo/
│   │   │           │           └── sample/
│   │   │           │               └── http/
│   │   │           │                   └── order/
│   │   │           │                       ├── service/
│   │   │           │                       │   ├── AccountServiceImpl.java
│   │   │           │                       │   ├── PaymentServiceImpl.java
│   │   │           │                       │   ├── PlaceOrderServiceImpl.java
│   │   │           │                       │   └── TradeOrderServiceProxy.java
│   │   │           │                       └── web/
│   │   │           │                           └── controller/
│   │   │           │                               ├── OrderController.java
│   │   │           │                               └── vo/
│   │   │           │                                   └── PlaceOrderRequest.java
│   │   │           ├── resources/
│   │   │           │   ├── config/
│   │   │           │   │   └── spring/
│   │   │           │   │       └── local/
│   │   │           │   │           ├── appcontext-service-consumer.xml
│   │   │           │   │           ├── appcontext-service-tcc.xml
│   │   │           │   │           └── appcontext-web-servlet.xml
│   │   │           │   ├── log/
│   │   │           │   │   └── log4j.xml
│   │   │           │   ├── sample-dubbo-order.properties
│   │   │           │   └── tccjdbc.properties
│   │   │           └── webapp/
│   │   │               └── WEB-INF/
│   │   │                   ├── ftl/
│   │   │                   │   ├── index.ftl
│   │   │                   │   ├── pay_success.ftl
│   │   │                   │   ├── product_detail.ftl
│   │   │                   │   └── shop.ftl
│   │   │                   └── web.xml
│   │   ├── tyloo-http-redpacket/
│   │   │   ├── pom.xml
│   │   │   └── src/
│   │   │       └── main/
│   │   │           ├── java/
│   │   │           │   └── io/
│   │   │           │       └── tyloo/
│   │   │           │           └── sample/
│   │   │           │               └── http/
│   │   │           │                   └── redpacket/
│   │   │           │                       └── service/
│   │   │           │                           ├── RedPacketAccountServiceImpl.java
│   │   │           │                           └── RedPacketTradeOrderServiceImpl.java
│   │   │           ├── resources/
│   │   │           │   ├── config/
│   │   │           │   │   └── spring/
│   │   │           │   │       └── local/
│   │   │           │   │           ├── appcontext-service-provider.xml
│   │   │           │   │           ├── appcontext-service-tcc.xml
│   │   │           │   │           └── appcontext-web-servlet.xml
│   │   │           │   ├── log/
│   │   │           │   │   └── log4j.xml
│   │   │           │   └── tccjdbc.properties
│   │   │           └── webapp/
│   │   │               ├── WEB-INF/
│   │   │               │   └── web.xml
│   │   │               └── index.jsp
│   │   └── tyloo-http-redpacket-api/
│   │       ├── pom.xml
│   │       └── src/
│   │           └── main/
│   │               └── java/
│   │                   └── io/
│   │                       └── tyloo/
│   │                           └── sample/
│   │                               └── http/
│   │                                   └── redpacket/
│   │                                       └── api/
│   │                                           ├── RedPacketAccountService.java
│   │                                           ├── RedPacketTradeOrderService.java
│   │                                           └── dto/
│   │                                               └── RedPacketTradeOrderDto.java
│   └── tyloo-sample-domain/
│       ├── pom.xml
│       ├── tyloo-sample-captial/
│       │   ├── pom.xml
│       │   └── src/
│       │       └── main/
│       │           ├── java/
│       │           │   └── io/
│       │           │       └── tyloo/
│       │           │           └── sample/
│       │           │               └── capital/
│       │           │                   ├── domain/
│       │           │                   │   ├── entity/
│       │           │                   │   │   ├── CapitalAccount.java
│       │           │                   │   │   └── TradeOrder.java
│       │           │                   │   └── repository/
│       │           │                   │       ├── CapitalAccountRepository.java
│       │           │                   │       └── TradeOrderRepository.java
│       │           │                   └── infrastructure/
│       │           │                       └── dao/
│       │           │                           ├── CapitalAccountDao.java
│       │           │                           └── TradeOrderDao.java
│       │           └── resources/
│       │               ├── config/
│       │               │   ├── spring/
│       │               │   │   └── local/
│       │               │   │       ├── appcontext-service-dao.xml
│       │               │   │       └── appcontext-service-datasource.xml
│       │               │   └── sqlmap/
│       │               │       └── main/
│       │               │           ├── sample-capitalaccount.xml
│       │               │           └── sample-tradeorder.xml
│       │               ├── jdbc.properties
│       │               └── log/
│       │                   └── log4j.xml
│       ├── tyloo-sample-common/
│       │   ├── pom.xml
│       │   └── src/
│       │       └── main/
│       │           └── java/
│       │               └── io/
│       │                   └── tyloo/
│       │                       └── sample/
│       │                           └── exception/
│       │                               └── InsufficientBalanceException.java
│       ├── tyloo-sample-order/
│       │   ├── pom.xml
│       │   └── src/
│       │       └── main/
│       │           ├── java/
│       │           │   └── io/
│       │           │       └── tyloo/
│       │           │           └── sample/
│       │           │               └── order/
│       │           │                   ├── domain/
│       │           │                   │   ├── entity/
│       │           │                   │   │   ├── Order.java
│       │           │                   │   │   ├── OrderLine.java
│       │           │                   │   │   ├── Product.java
│       │           │                   │   │   └── Shop.java
│       │           │                   │   ├── factory/
│       │           │                   │   │   └── OrderFactory.java
│       │           │                   │   ├── repository/
│       │           │                   │   │   ├── OrderRepository.java
│       │           │                   │   │   ├── ProductRepository.java
│       │           │                   │   │   └── ShopRepository.java
│       │           │                   │   └── service/
│       │           │                   │       └── OrderServiceImpl.java
│       │           │                   └── infrastructure/
│       │           │                       └── dao/
│       │           │                           ├── OrderDao.java
│       │           │                           ├── OrderLineDao.java
│       │           │                           ├── ProductDao.java
│       │           │                           └── ShopDao.java
│       │           └── resources/
│       │               ├── config/
│       │               │   ├── spring/
│       │               │   │   └── local/
│       │               │   │       ├── appcontext-service-dao.xml
│       │               │   │       └── appcontext-service-datasource.xml
│       │               │   └── sqlmap/
│       │               │       └── main/
│       │               │           ├── sample-order.xml
│       │               │           ├── sample-orderline.xml
│       │               │           ├── sample-product.xml
│       │               │           └── sample-shop.xml
│       │               ├── jdbc.properties
│       │               ├── log/
│       │               │   └── log4j.xml
│       │               └── sample-order.properties
│       └── tyloo-sample-redpacket/
│           ├── pom.xml
│           └── src/
│               └── main/
│                   ├── java/
│                   │   └── io/
│                   │       └── tyloo/
│                   │           └── sample/
│                   │               └── redpacket/
│                   │                   ├── domain/
│                   │                   │   ├── entity/
│                   │                   │   │   ├── RedPacketAccount.java
│                   │                   │   │   └── TradeOrder.java
│                   │                   │   └── repository/
│                   │                   │       ├── RedPacketAccountRepository.java
│                   │                   │       └── TradeOrderRepository.java
│                   │                   └── infrastructure/
│                   │                       └── dao/
│                   │                           ├── RedPacketAccountDao.java
│                   │                           └── TradeOrderDao.java
│                   └── resources/
│                       ├── config/
│                       │   ├── spring/
│                       │   │   └── local/
│                       │   │       ├── appcontext-service-dao.xml
│                       │   │       └── appcontext-service-datasource.xml
│                       │   └── sqlmap/
│                       │       └── main/
│                       │           ├── sample-redpacketaccount.xml
│                       │           └── sample-tradeorder.xml
│                       ├── jdbc.properties
│                       └── log/
│                           └── log4j.xml
└── tyloo-unit-test/
    ├── pom.xml
    └── src/
        ├── main/
        │   ├── java/
        │   │   └── io/
        │   │       └── tyloo/
        │   │           └── unittest/
        │   │               ├── client/
        │   │               │   ├── AccountRecordServiceProxy.java
        │   │               │   ├── AccountServiceProxy.java
        │   │               │   └── TransferService.java
        │   │               ├── entity/
        │   │               │   ├── AccountRecord.java
        │   │               │   ├── AccountStatus.java
        │   │               │   ├── SubAccount.java
        │   │               │   └── UserShardingId.java
        │   │               ├── repository/
        │   │               │   ├── AccountRecordRepository.java
        │   │               │   └── SubAccountRepository.java
        │   │               ├── service/
        │   │               │   ├── AccountService.java
        │   │               │   └── AccountServiceImpl.java
        │   │               ├── thirdservice/
        │   │               │   ├── AccountRecordService.java
        │   │               │   └── AccountRecordServiceImpl.java
        │   │               └── utils/
        │   │                   └── UnitTest.java
        │   └── resources/
        │       └── tyloo-unit-test.xml
        └── test/
            ├── java/
            │   └── io/
            │       └── tyloo/
            │           └── unit/
            │               └── test/
            │                   ├── AbstractTestCase.java
            │                   ├── PerformanceTest.java
            │                   ├── ReflectionTest.java
            │                   └── TransferServiceTest.java
            └── resources/
                └── log4j.properties

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# maven ignore
target/
*.jar
*.war
*.zip
*.tar
*.tar.gz

# eclipse ignore
.settings/
.project
.classpath

# idea ignore
.idea/
*.ipr
*.iml
*.iws

# temp ignore
*.log
*.cache
*.diff
*.patch
*.tmp

# system ignore
.DS_Store
Thumbs.db


================================================
FILE: README.md
================================================
# tyloo
Distributed transaction framework——TCC



## 概念

- Try: 尝试执行业务
  - 完成所有业务检查(一致性)
  - 预留必须业务资源(准隔离性)

- Confirm: 确认执行业务
  - 真正执行业务
  - 不作任何业务检查
  - 只使用Try阶段预留的业务资源
  - Confirm操作满足幂等性 

- Cancel: 取消执行业务

  - 释放Try阶段预留的业务资源
  - Cancel操作满足幂等性

  



## 环境

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





## 功能

- 基于 Spring AOP 切面思想实现对分布式事务注解的拦截。
- 基于Dubbo的ProxyFactory代理机制为服务接口生成代理对象。
- 基于Mysql、Redis乐观锁进行事务版本控制以及基于基于Quartz进行事务恢复。
- 支持多种事务日志序列化以及事务存储器实现。
- 调用方式(版本):Dubbo、HTTP





## 业务场景

- https://www.cnblogs.com/jajian/p/10014145.html

- **我们有必要使用TCC分布式事务机制来保证各个服务形成一个整体性的事务**







## 运行

1. 导入数据库脚本`tyloo/tyloo-tutorial-sample/src/tylooSampledb`
2. 修改三个配置文件`tccjdbc.properties`
3. 修改三个子项目(capital、redpacket、order)的启动配置:HTTP port







## 模块

- **两个拦截器**

  - 通过对 @Tyloo AOP 切面( 参与者 try 方法 )进行拦截,透明化对参与者confirm / cancel 方法调用,从而实现 TCC

- **事务与参与者**

  - TCC 通过多个参与者的 try / confirm / cancel 方法,实现事务的最终一致性
  - Tyloo 将每个业务操作抽象成事务参与者

- **事务管理器**

  - 提供事务的获取、发起、提交、回滚,参与者的新增等等方法。

- **事务存储器**

  - 提供对事务对象的持久化

- **事务注解**

  - 传播级别
  - 确认/取消执行业务方法
  - 事务上下文编辑

- **事务恢复**

  - 事务信息被持久化到外部的存储器中。事务存储是事务恢复的基础。通过读取外部存储器中的异常事务,定时任务会按照一定频率对事务进行重试,直到事务完成或超过最大重试次数。

  





## 流程

- 因为对远程业务的调用需要用到代理对象,代理对象由dubbo service生成,TRY阶段在进行远程调用前需要调用代理对象(代理对象的confrimmethod和cancelmethod均和try方法名字相同),此时拦截器会进行拦截代理对象,拦截后调用远程业务,远程业务(远程业务本地有个本地事务保证执行成功)也会被拦截,然后远程业务执行。COMMIT阶段时主业务执行完comfirm方法后代理对象执行comfirm方法(confirm方法均为反射调用),但是代理对象的confirm方法还是代理对象的try方法,此时再被拦截器拦截,因为此时代理对象的事务状态已经改为CONFIRMING,由于事务类型为defalut(因为代理对象的传播级别默认为SUPPORT),所以直接过了。此时再调用远程业务的try方法,走拦截,invoke反射的时候反射远程业务的confrim方法,因为try方法做了幂等所以直接过了,此时远程业务的commit阶段完成,然后继续下一个远程业务。最后根事务提交,完成。

















================================================
FILE: pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>io.tyloo</groupId>
    <artifactId>tyloo</artifactId>
    <packaging>pom</packaging>
    <version>1.1.0</version>

    <modules>
        <module>tyloo-api</module>
        <module>tyloo-core</module>
        <module>tyloo-spring</module>
        <module>tyloo-unit-test</module>
        <module>tyloo-tutorial-sample</module>
        <module>tyloo-server</module>
        <module>tyloo-dubbo</module>
        <module>tyloo-bom</module>
    </modules>

    <properties>

        <java.src.version>1.8</java.src.version>
        <java.target.version>1.8</java.target.version>
        <project.encoding>GBK</project.encoding>
        <springframework.version>4.3.18.RELEASE</springframework.version>
        <aspectj.version>1.9.2</aspectj.version>
        <slf4j.version>1.7.9</slf4j.version>
        <dubbo.version>2.7.4.1</dubbo.version>

    </properties>


    <dependencyManagement>

        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-framework-bom</artifactId>
                <version>${springframework.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>com.fasterxml.jackson</groupId>
                <artifactId>jackson-bom</artifactId>
                <version>2.10.1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo</artifactId>
                <version>${dubbo.version}</version>
            </dependency>

            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-dependencies-zookeeper</artifactId>
                <version>${dubbo.version}</version>
                <type>pom</type>
            </dependency>

            <dependency>
                <groupId>com.mchange</groupId>
                <artifactId>c3p0</artifactId>
                <version>0.9.5.4</version>
            </dependency>

            <dependency>
                <groupId>org.quartz-scheduler</groupId>
                <artifactId>quartz</artifactId>
                <version>2.3.2</version>
            </dependency>

            <dependency>
                <groupId>com.esotericsoftware</groupId>
                <artifactId>kryo</artifactId>
                <version>4.0.2</version>
            </dependency>

            <dependency>
                <groupId>com.google.guava</groupId>
                <artifactId>guava</artifactId>
                <version>19.0</version>
            </dependency>

            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
                <version>4.5.10</version>
            </dependency>

            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.62</version>
            </dependency>

            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjrt</artifactId>
                <version>${aspectj.version}</version>
            </dependency>

            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>${aspectj.version}</version>
            </dependency>

            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>3.9</version>
            </dependency>

            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>${slf4j.version}</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>jcl-over-slf4j</artifactId>
                <version>${slf4j.version}</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>${slf4j.version}</version>
            </dependency>

            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>

            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.48</version>
            </dependency>

            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>

            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.2.8</version>
            </dependency>

            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-spring</artifactId>
                <version>1.2.2</version>
            </dependency>

            <dependency>
                <groupId>redis.clients</groupId>
                <artifactId>jedis</artifactId>
                <version>2.9.0</version>
            </dependency>

            <dependency>
                <groupId>org.freemarker</groupId>
                <artifactId>freemarker</artifactId>
                <version>2.3.29</version>
            </dependency>

            <dependency>
                <groupId>commons-codec</groupId>
                <artifactId>commons-codec</artifactId>
                <version>1.11</version>
            </dependency>

            <dependency>
                <groupId>io.tyloo</groupId>
                <artifactId>tyloo-api</artifactId>
                <version>${project.version}</version>
            </dependency>

            <dependency>
                <groupId>io.tyloo</groupId>
                <artifactId>tyloo-core</artifactId>
                <version>${project.version}</version>
            </dependency>

        </dependencies>

    </dependencyManagement>


    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
        <testResources>
            <testResource>
                <directory>src/test/resources</directory>
                <filtering>true</filtering>
            </testResource>
        </testResources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <encoding>${project.encoding}</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <source>${java.src.version}</source>
                    <target>${java.target.version}</target>
                    <encoding>${project.encoding}</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-eclipse-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <workspace>${basedir}</workspace>
                    <workspaceCodeStylesURL>
                        http://svn.apache.org/repos/asf/maven/plugins/trunk/maven-eclipse-plugin/src/optional/eclipse-config/maven-styles.xml
                    </workspaceCodeStylesURL>
                    <downloadSources>true</downloadSources>
                    <downloadJavadocs>false</downloadJavadocs>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>2.2.1</version>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <version>2.7</version>
                <configuration>
                    <updateReleaseInfo>true</updateReleaseInfo>
                </configuration>
            </plugin>
        </plugins>

    </build>


</project>

================================================
FILE: tyloo-api/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>tyloo</artifactId>
        <groupId>io.tyloo</groupId>
       <version>1.1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>tyloo-api</artifactId>
    <dependencies>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.2.5</version>
        </dependency>
    </dependencies>

</project>

================================================
FILE: tyloo-api/src/main/java/io/tyloo/api/Propagation.java
================================================
package io.tyloo.api;

/*
 *
 * 
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 11:49 2019/4/4
 *
 */

public enum Propagation {
    /**
     * ֵ֧ǰǰû񣬾½һ
     */
    REQUIRED(0),
    /**
     * ֵ֧ǰǰû񣬾Էʽִ
     */
    SUPPORTS(1),
    /**
     * ֵ֧ǰǰû񣬾׳쳣
     */
    MANDATORY(2),
    /**
     * ½ǰ񣬰ѵǰ
     */
    REQUIRES_NEW(3);

    private final int value;

    Propagation(int value) {
        this.value = value;
    }

    public int value() {
        return this.value;
    }
}

================================================
FILE: tyloo-api/src/main/java/io/tyloo/api/TransactionContext.java
================================================
package io.tyloo.api;

import java.io.Serializable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/*
 *
 * 
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 12:01 2019/4/6
 *
 */
public class TransactionContext implements Serializable {

    private static final long serialVersionUID = -8199390103169700387L;

    private TransactionXid xid;

    private int status;

    private Map<String, String> attachments = new ConcurrentHashMap<String, String>();

    public TransactionContext() {

    }

    public TransactionContext(TransactionXid xid, int status) {
        this.xid = xid;
        this.status = status;
    }

    public void setXid(TransactionXid xid) {
        this.xid = xid;
    }

    public TransactionXid getXid() throws CloneNotSupportedException {
        return xid.clone();
    }

    public void setAttachments(Map<String, String> attachments) {
        if (attachments != null && !attachments.isEmpty()) {
            this.attachments.putAll(attachments);
        }
    }

    public Map<String, String> getAttachments() {
        return attachments;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public int getStatus() {
        return status;
    }


}


================================================
FILE: tyloo-api/src/main/java/io/tyloo/api/TransactionContextEditor.java
================================================
package io.tyloo.api;

import java.lang.reflect.Method;

/*
 *
 * ı༭úͻ
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 11:35 2019/4/7
 *
 */

public interface TransactionContextEditor {
    /**
     * Ӳл
     *
     * @param target 
     * @param method 
     * @param args   
     * @return 
     */

    TransactionContext get(Object target, Method method, Object[] args);
    /**
     * ĵ
     *
     * @param transactionContext 
     * @param target             
     * @param method             
     * @param args               
     */
    void set(TransactionContext transactionContext, Object target, Method method, Object[] args);

}


================================================
FILE: tyloo-api/src/main/java/io/tyloo/api/TransactionStatus.java
================================================
package io.tyloo.api;

/*
 *
 * ״̬ö
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 12:05 2019/4/5
 *
 */
public enum TransactionStatus {

    /**
     * try׶
     */
    TRYING(1),

    /**
     * confirm׶
     */
    CONFIRMING(2),

    /**
     * cancel׶
     */
    CANCELLING(3);

    private int id;

     TransactionStatus(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public static TransactionStatus valueOf(int id) {

        switch (id) {
            case 1:
                return TRYING;
            case 2:
                return CONFIRMING;
            default:
                return CANCELLING;
        }
    }

}


================================================
FILE: tyloo-api/src/main/java/io/tyloo/api/TransactionXid.java
================================================
package io.tyloo.api;


import javax.transaction.xa.Xid;
import java.io.Serializable;
import java.nio.ByteBuffer;
import java.util.Arrays;

import cn.hutool.core.lang.UUID;

/*
 * xidţΨһʶһʹ UUID 㷨ɣ֤Ψһԡ
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 14:57 2019/4/10
 *
 */
public class TransactionXid implements Xid, Serializable {

    private static final long serialVersionUID = -6817267250789142043L;
    /**
     * XID ĸʽʶ
     * һ֣ڱʶglobalTransactionIdbranchQualifierֵʹõĸʽĬֵ1
     */
    private int formatId = 1;
    /**
     * ȫID.
     * ͬķֲʽӦʹͬglobalTransactionIdȷ֪XAĸֲʽ
     */
    private byte[] globalTransactionId;
    /**
     * ֧޶.
     * Ĭֵǿմһֲʽеÿ֧bqualֵΨһ
     */
    private byte[] branchQualifier;

    private static byte[] CUSTOMIZED_TRANSACTION_ID = "UniqueIdentity".getBytes();

    public TransactionXid() {
        globalTransactionId = uuidToByteArray(UUID.randomUUID());
        branchQualifier = uuidToByteArray(UUID.randomUUID());
    }

    public void setGlobalTransactionId(byte[] globalTransactionId) {
        this.globalTransactionId = globalTransactionId;
    }

    public void setBranchQualifier(byte[] branchQualifier) {
        this.branchQualifier = branchQualifier;
    }

    public TransactionXid(Object uniqueIdentity) {

        if (uniqueIdentity == null) {

            globalTransactionId = uuidToByteArray(UUID.randomUUID());
            branchQualifier = uuidToByteArray(UUID.randomUUID());

        } else {

            this.globalTransactionId = CUSTOMIZED_TRANSACTION_ID;

            this.branchQualifier = uniqueIdentity.toString().getBytes();
        }
    }

    public TransactionXid(byte[] globalTransactionId) {
        this.globalTransactionId = globalTransactionId;
        this.branchQualifier = uuidToByteArray(UUID.randomUUID());
    }

    public TransactionXid(byte[] globalTransactionId, byte[] branchQualifier) {
        this.globalTransactionId = globalTransactionId;
        this.branchQualifier = branchQualifier;
    }

    /**
     * ȡ XID ĸʽʶ֡
     */
    @Override
    public int getFormatId() {
        return formatId;
    }

    /**
     * ȡ XID ȫʶΪֽ顣
     */
    @Override
    public byte[] getGlobalTransactionId() {
        return globalTransactionId;
    }

    /**
     * ȡ XID ֧ʶΪֽ顣
     */
    @Override
    public byte[] getBranchQualifier() {
        return branchQualifier;
    }

    @Override
    public String toString() {

        StringBuilder stringBuilder = new StringBuilder();
        if (Arrays.equals(CUSTOMIZED_TRANSACTION_ID, globalTransactionId)) {

            stringBuilder.append(new String(globalTransactionId));
            stringBuilder.append(":").append(new String(branchQualifier));

        } else {

            stringBuilder.append(UUID.nameUUIDFromBytes(globalTransactionId).toString());
            stringBuilder.append(":").append(UUID.nameUUIDFromBytes(branchQualifier).toString());
        }

        return stringBuilder.toString();
    }

    @Override
    public TransactionXid clone() throws CloneNotSupportedException {

        TransactionXid clone = (TransactionXid) super.clone();

        byte[] cloneGlobalTransactionId = null;
        byte[] cloneBranchQualifier = null;

        if (globalTransactionId != null) {
            cloneGlobalTransactionId = new byte[globalTransactionId.length];
            System.arraycopy(globalTransactionId, 0, cloneGlobalTransactionId, 0, globalTransactionId.length);
        }

        if (branchQualifier != null) {
            cloneBranchQualifier = new byte[branchQualifier.length];
            System.arraycopy(branchQualifier, 0, cloneBranchQualifier, 0, branchQualifier.length);
        }

        return new TransactionXid(cloneGlobalTransactionId, cloneBranchQualifier);
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + this.getFormatId();
        result = prime * result + Arrays.hashCode(branchQualifier);
        result = prime * result + Arrays.hashCode(globalTransactionId);
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        return this == obj;

    }

    private static byte[] uuidToByteArray(UUID uuid) {
        ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
        bb.putLong(uuid.getMostSignificantBits()).putLong(uuid.getLeastSignificantBits());
        return bb.array();
    }

}




================================================
FILE: tyloo-api/src/main/java/io/tyloo/api/Tyloo.java
================================================
package io.tyloo.api;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;

/*
 *
 * ע
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 11:32 2019/4/1
 *
 *
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Tyloo {

    /**
     * 
     */
    Propagation propagation() default Propagation.REQUIRED;

    /**
     * ȷִҵ񷽷
     */
    String confirmMethod() default "";

    /**
     * ȡִҵ񷽷
     */
    String cancelMethod() default "";

    /**
     * ı༭
     */
    public Class<? extends TransactionContextEditor> transactionContextEditor() default DefaultTransactionContextEditor.class;

    /**
     * ʱ쳣
     * delayCancelExceptions()ʾϵͳõ쳣ʱrollbacɻָjobִָk
     * ͨҪʱ쳣ΪdelayCancelExceptionsԱΪʱ˳ʱ쳣rollback, Ǵûִ꣬Ӷrollbackʧ
     *
     * @return
     */
    public Class<? extends Exception>[] delayCancelExceptions() default {};

    public boolean asyncConfirm() default false;

    public boolean asyncCancel() default false;

    /**
     * Ĭı༭ʵ
     */
    class DefaultTransactionContextEditor implements TransactionContextEditor {

        @Override
        public TransactionContext get(Object target, Method method, Object[] args) {
            int position = getTransactionContextParamPosition(method.getParameterTypes());

            if (position >= 0) {
                return (TransactionContext) args[position];
            }

            return null;
        }

        @Override
        public void set(TransactionContext transactionContext, Object target, Method method, Object[] args) {

            int position = getTransactionContextParamPosition(method.getParameterTypes());
            if (position >= 0) {
                args[position] = transactionContext;
            }
        }

        /**
         * ڷλ
         *
         * @param parameterTypes ͼ
         * @return λ
         */
        static int getTransactionContextParamPosition(Class<?>[] parameterTypes) {

            int position = -1;

            for (int i = 0; i < parameterTypes.length; i++) {
                if (parameterTypes[i].equals(TransactionContext.class)) {
                    position = i;
                    break;
                }
            }
            return position;
        }

        /**
         * @param args б
         * @return ȡTransactionContext
         */
        public static TransactionContext getTransactionContextFromArgs(Object[] args) {

            TransactionContext transactionContext = null;

            for (Object arg : args) {
                if (arg != null && TransactionContext.class.isAssignableFrom(arg.getClass())) {

                    transactionContext = (TransactionContext) arg;
                }
            }

            return transactionContext;
        }
    }
}

================================================
FILE: tyloo-api/src/main/java/io/tyloo/api/UniqueIdentity.java
================================================
package io.tyloo.api;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/*
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 16:40 2019/4/6
 *
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
public @interface UniqueIdentity {
}


================================================
FILE: tyloo-api/src/main/java/io/tyloo/api/UuidUtils.java
================================================
package io.tyloo.api;

import java.nio.ByteBuffer;

import cn.hutool.core.lang.UUID;

/*
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 15:06 2019/4/4
 *
 */

public class UuidUtils {

    public static byte[] uuidToByteArray(UUID uuid) {
        ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
        bb.putLong(uuid.getMostSignificantBits());
        bb.putLong(uuid.getLeastSignificantBits());
        return bb.array();
    }

    public static UUID byteArrayToUUID(byte[] bytes) {
        ByteBuffer bb = ByteBuffer.wrap(bytes);
        long firstLong = bb.getLong();
        long secondLong = bb.getLong();
        return new UUID(firstLong, secondLong);
    }
}



================================================
FILE: tyloo-core/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>tyloo</artifactId>
        <groupId>io.tyloo</groupId>
        <version>1.1.0</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>

    <artifactId>tyloo-core</artifactId>

    <dependencies>

        <dependency>
            <groupId>io.tyloo</groupId>
            <artifactId>tyloo-api</artifactId>
        </dependency>



        <dependency>
            <groupId>com.esotericsoftware</groupId>
            <artifactId>kryo</artifactId>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </dependency>

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
        </dependency>

        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
        </dependency>

    </dependencies>


</project>

================================================
FILE: tyloo-core/src/main/java/io/tyloo/CancellingException.java
================================================
package io.tyloo;

/*
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:55 2019/6/1
 *
 */
public class CancellingException extends RuntimeException {


    public CancellingException(Throwable cause) {
        super(cause);
    }
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/ConcurrentTransactionException.java
================================================
package io.tyloo;

/*
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:55 2019/6/1
 *
 */
public class ConcurrentTransactionException extends RuntimeException {
    private static final long serialVersionUID = 4099060614687283527L;

    public ConcurrentTransactionException() {

    }

    public ConcurrentTransactionException(String message) {
        super(message);
    }

    public ConcurrentTransactionException(String message, Throwable e) {
        super(message, e);
    }
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/ConfirmingException.java
================================================
package io.tyloo;

/*
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:55 2019/6/1
 *
 */
public class ConfirmingException extends RuntimeException {

    public ConfirmingException(Throwable cause) {
        super(cause);
    }
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/InvocationContext.java
================================================
package io.tyloo;

import java.io.Serializable;

/*
 *
 *  ִз
 *  ¼ࡢ顢顣
 *  ͨЩԣִύ / ع
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 15:48 2019/6/3
 *
 */
public class InvocationContext implements Serializable {

    private static final long serialVersionUID = -7969140711432461165L;

    /**
     * 
     */
    private Class targetClass;

    /**
     * 
     */
    private String methodName;

    /**
     * 
     */
    private Class[] parameterTypes;

    /**
     * 
     */
    private Object[] args;

    public InvocationContext() {

    }

    public InvocationContext(Class targetClass, String methodName, Class[] parameterTypes, Object... args) {
        this.methodName = methodName;
        this.parameterTypes = parameterTypes;
        this.targetClass = targetClass;
        this.args = args;
    }

    public Object[] getArgs() {
        return args;
    }

    public Class getTargetClass() {
        return targetClass;
    }

    public String getMethodName() {
        return methodName;
    }

    public Class[] getParameterTypes() {
        return parameterTypes;
    }
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/NoExistedTransactionException.java
================================================
package io.tyloo;

/*
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:55 2019/6/1
 *
 */
public class NoExistedTransactionException extends Exception {
    private static final long serialVersionUID = 1031919168789207713L;
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/OptimisticLockException.java
================================================
package io.tyloo;

/*
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:55 2019/6/1
 *
 */
public class OptimisticLockException extends RuntimeException {
    private static final long serialVersionUID = -4250747002159020605L;
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/Participant.java
================================================
package io.tyloo;

import io.tyloo.api.TransactionContext;
import io.tyloo.api.TransactionContextEditor;
import io.tyloo.api.TransactionStatus;
import io.tyloo.api.TransactionXid;

import java.io.Serializable;

/*
 *
 * 
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 20:00 2019/6/5
 *
 */

public class Participant implements Serializable {

    private static final long serialVersionUID = 4127729421281425247L;

    private TransactionXid xid;

    private InvocationContext confirmInvocationContext;

    private InvocationContext cancelInvocationContext;

    Class<? extends TransactionContextEditor> transactionContextEditorClass;

    public Participant() {

    }

    public Participant(TransactionXid xid, InvocationContext confirmInvocationContext, InvocationContext cancelInvocationContext, Class<? extends TransactionContextEditor> transactionContextEditorClass) {
        this.xid = xid;
        this.confirmInvocationContext = confirmInvocationContext;
        this.cancelInvocationContext = cancelInvocationContext;
        this.transactionContextEditorClass = transactionContextEditorClass;
    }

    public Participant(InvocationContext confirmInvocationContext, InvocationContext cancelInvocationContext, Class<? extends TransactionContextEditor> transactionContextEditorClass) {
        this.confirmInvocationContext = confirmInvocationContext;
        this.cancelInvocationContext = cancelInvocationContext;
        this.transactionContextEditorClass = transactionContextEditorClass;
    }

    public void setXid(TransactionXid xid) {
        this.xid = xid;
    }

    public void rollback() {
        Terminator.invoke(new TransactionContext(xid, TransactionStatus.CANCELLING.getId()), cancelInvocationContext, transactionContextEditorClass);
    }

    public void commit() {
        Terminator.invoke(new TransactionContext(xid, TransactionStatus.CONFIRMING.getId()), confirmInvocationContext, transactionContextEditorClass);
    }

    public TransactionXid getXid() {
        return xid;
    }

    public InvocationContext getConfirmInvocationContext() {
        return confirmInvocationContext;
    }

    public InvocationContext getCancelInvocationContext() {
        return cancelInvocationContext;
    }

}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/SystemException.java
================================================
package io.tyloo;

/*
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:55 2019/6/1
 *
 */
public class SystemException extends RuntimeException {

    public SystemException(String message) {
        super(message);
    }

    public SystemException(Throwable e) {
        super(e);
    }

    public SystemException(String message, Throwable e) {
        super(message, e);
    }
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/Terminator.java
================================================
package io.tyloo;

import io.tyloo.api.TransactionContext;
import io.tyloo.api.TransactionContextEditor;
import io.tyloo.support.FactoryBuilder;
import io.tyloo.utils.StringUtils;

import java.lang.reflect.Method;

/*
 *
 * ִ
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 20:01 2019/6/6
 *
 */

public final class Terminator {

    public Terminator() {

    }

    /**
     * ݵģȡĿ귽ִз.
     *
     * @param invocationContext
     */
    public static void invoke(TransactionContext transactionContext, InvocationContext invocationContext, Class<? extends TransactionContextEditor> transactionContextEditorClass) {


        if (StringUtils.isNotEmpty(invocationContext.getMethodName())) {

            try {

                Object target = FactoryBuilder.factoryOf(invocationContext.getTargetClass()).getInstance();

                Method method = null;

                //ע
                method = target.getClass().getMethod(invocationContext.getMethodName(), invocationContext.getParameterTypes());

                FactoryBuilder.factoryOf(transactionContextEditorClass).getInstance().set(transactionContext, target, method, invocationContext.getArgs());

                // ÷񷽷ٴαTylooAspectTylooCoordinatorAspectأΪ״̬ѾTRYINGˣֱִԶ̷
                method.invoke(target, invocationContext.getArgs());

            } catch (Exception e) {
                throw new SystemException(e);
            }
        }
    }
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/Transaction.java
================================================
package io.tyloo;


import io.tyloo.api.TransactionContext;
import io.tyloo.api.TransactionStatus;
import io.tyloo.api.TransactionXid;
import io.tyloo.common.TransactionType;

import javax.transaction.xa.Xid;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/*
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 18:04 2019/4/30
 *
 */

public class Transaction implements Serializable  {

    private static final long serialVersionUID = 7291423944314337931L;

    private TransactionXid xid;

    private TransactionStatus status;

    private TransactionType transactionType;

    private volatile int retriedCount = 0;

    private Date createTime = new Date();

    private Date lastUpdateTime = new Date();

    private long version = 1;

    private List<Participant> participants = new ArrayList<Participant>();

    private Map<String, Object> attachments = new ConcurrentHashMap<String, Object>();

    public Transaction() {

    }

    public Transaction(TransactionContext transactionContext) throws CloneNotSupportedException {
        this.xid = transactionContext.getXid();
        this.status = TransactionStatus.TRYING;
        this.transactionType = TransactionType.BRANCH;
    }

    public Transaction(TransactionType transactionType) {
        this.xid = new TransactionXid();
        this.status = TransactionStatus.TRYING;
        this.transactionType = transactionType;
    }

    public Transaction(Object uniqueIdentity,TransactionType transactionType) {

        this.xid = new TransactionXid(uniqueIdentity);
        this.status = TransactionStatus.TRYING;
        this.transactionType = transactionType;
    }

    public void enlistParticipant(Participant participant) {
        participants.add(participant);
    }

    public Xid getXid() {
        try {
            return xid.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }

    public TransactionStatus getStatus() {
        return status;
    }


    public List<Participant> getParticipants() {
        return participants;
    }

    public TransactionType getTransactionType() {
        return transactionType;
    }

    public void changeStatus(TransactionStatus status) {
        this.status = status;
    }


    public void commit() {

        for (Participant participant : participants) {
            participant.commit();
        }
    }

    public void rollback() {
        for (Participant participant : participants) {
            participant.rollback();
        }
    }

    public int getRetriedCount() {
        return retriedCount;
    }

    public void addRetriedCount() {
        this.retriedCount++;
    }

    public void resetRetriedCount(int retriedCount) {
        this.retriedCount = retriedCount;
    }

    public Map<String, Object> getAttachments() {
        return attachments;
    }

    public long getVersion() {
        return version;
    }

    public void updateVersion() {
        this.version++;
    }

    public void setVersion(long version) {
        this.version = version;
    }

    public Date getLastUpdateTime() {
        return lastUpdateTime;
    }

    public void setLastUpdateTime(Date date) {
        this.lastUpdateTime = date;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void updateTime() {
        this.lastUpdateTime = new Date();
    }


}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/TransactionManager.java
================================================
package io.tyloo;

import io.tyloo.api.TransactionContext;
import io.tyloo.api.TransactionStatus;
import io.tyloo.common.TransactionType;
import org.apache.log4j.Logger;

import java.util.Deque;
import java.util.LinkedList;
import java.util.concurrent.ExecutorService;

/*
 *
 * 
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 20:25 2019/6/7
 *
 */

public class TransactionManager {

    static final Logger logger = Logger.getLogger(TransactionManager.class.getSimpleName());

    private TransactionRepository transactionRepository;

    /**
     * ǰ߳
     */
    private static final ThreadLocal<Deque<Transaction>> CURRENT = new ThreadLocal<Deque<Transaction>>();

    private ExecutorService executorService;

    public void setTransactionRepository(TransactionRepository transactionRepository) {
        this.transactionRepository = transactionRepository;
    }

    public void setExecutorService(ExecutorService executorService) {
        this.executorService = executorService;
    }

    public TransactionManager() {


    }

    /**
     *
     * 
     *  begin ֮ʵҲʹһȫʵorder
     * Żص rootMethodProceed ִ
     *
     * @param uniqueIdentify
     * @return
     */
    public Transaction begin(Object uniqueIdentify) throws CloneNotSupportedException {
        Transaction transaction = new Transaction(uniqueIdentify, TransactionType.ROOT);
        transactionRepository.create(transaction);
        registerTransaction(transaction);
        return transaction;
    }


    /**
     * ֧
     *
     * @param transactionContext 
     * @return ֧
     */
    public Transaction propagationNewBegin(TransactionContext transactionContext) throws CloneNotSupportedException {

        Transaction transaction = new Transaction(transactionContext);
        transactionRepository.create(transaction);

        registerTransaction(transaction);
        return transaction;
    }

    /**
     * ȡ֧
     *
     * @param transactionContext 
     * @return ֧
     * @throws NoExistedTransactionException 񲻴ʱ
     */
    public Transaction propagationExistBegin(TransactionContext transactionContext) throws NoExistedTransactionException {
        Transaction transaction = null;
        try {
            transaction = transactionRepository.findByXid(transactionContext.getXid());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

        if (transaction != null) {
            transaction.changeStatus(TransactionStatus.valueOf(transactionContext.getStatus()));
            registerTransaction(transaction);
            return transaction;
        } else {
            throw new NoExistedTransactionException();
        }
    }

    public void commit(boolean asyncCommit) {

        final Transaction transaction = getCurrentTransaction();

        transaction.changeStatus(TransactionStatus.CONFIRMING);

        transactionRepository.update(transaction);

        if (asyncCommit) {
            try {
                Long statTime = System.currentTimeMillis();

                executorService.submit(new Runnable() {
                    @Override
                    public void run() {
                        commitTransaction(transaction);
                    }
                });
                logger.debug("async submit cost time:" + (System.currentTimeMillis() - statTime));
            } catch (Throwable commitException) {
                logger.warn("tyloo transaction async submit confirm failed, recovery job will try to confirm later.", commitException);
                throw new ConfirmingException(commitException);
            }
        } else {
            commitTransaction(transaction);
        }
    }


    public void rollback(boolean asyncRollback) {

        final Transaction transaction = getCurrentTransaction();
        transaction.changeStatus(TransactionStatus.CANCELLING);

        transactionRepository.update(transaction);

        if (asyncRollback) {

            try {
                executorService.submit(new Runnable() {
                    @Override
                    public void run() {
                        rollbackTransaction(transaction);
                    }
                });
            } catch (Throwable rollbackException) {
                logger.warn("tyloo transaction async rollback failed, recovery job will try to rollback later.", rollbackException);
                throw new CancellingException(rollbackException);
            }
        } else {

            rollbackTransaction(transaction);
        }
    }


    private void commitTransaction(Transaction transaction) {
        try {
            transaction.commit();
            transactionRepository.delete(transaction);
        } catch (Throwable commitException) {
            logger.warn("tyloo transaction confirm failed, recovery job will try to confirm later.", commitException);
            throw new ConfirmingException(commitException);
        }
    }

    private void rollbackTransaction(Transaction transaction) {
        try {
            transaction.rollback();
            transactionRepository.delete(transaction);
        } catch (Throwable rollbackException) {
            logger.warn("tyloo transaction rollback failed, recovery job will try to rollback later.", rollbackException);
            throw new CancellingException(rollbackException);
        }
    }

    /**
     * ȡǰ߳һ(ͷ)Ԫ
     *
     * @return 
     */
    public Transaction getCurrentTransaction() {
        if (isTransactionActive()) {
            return CURRENT.get().peek();
        }
        return null;
    }

    public boolean isTransactionActive() {
        Deque<Transaction> transactions = CURRENT.get();
        return transactions != null && !transactions.isEmpty();
    }

    /**
     * ע񵽵ǰ߳
     *
     * @param transaction 
     */
    private void registerTransaction(Transaction transaction) {

        if (CURRENT.get() == null) {
            CURRENT.set(new LinkedList<Transaction>());
        }

        CURRENT.get().push(transaction);
    }

    /**
     * ӵǰ߳Ƴ
     *
     * @param transaction 
     */
    public void cleanAfterCompletion(Transaction transaction) {
        if (isTransactionActive() && transaction != null) {
            Transaction currentTransaction = getCurrentTransaction();
            if (currentTransaction == transaction) {
                CURRENT.get().pop();
                if (CURRENT.get().size() == 0) {
                    CURRENT.remove();
                }
            } else {
                throw new SystemException("Illegal transaction when clean after completion");
            }
        }
    }

    /**
     * Ӳߵ
     *
     * @param participant 
     */
    public void enlistParticipant(Participant participant) {
        Transaction transaction = this.getCurrentTransaction();
        transaction.enlistParticipant(participant);
        transactionRepository.update(transaction);
    }
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/TransactionRepository.java
================================================
package io.tyloo;

import io.tyloo.api.TransactionXid;

import java.util.Date;
import java.util.List;

/*
 *
 * (tccݿdao)
 * ʵڱĿdubbo-orderеconfig.spring.localappcontext-service-dao.xmlã
 * ʵSpringJdbcTransactionRepository̳JdbcTransactionRepositoryΪordercapitalredpacket3ķ
 * ÿһģжappcontext-service-dao.xmlӳ
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:00 2019/6/12
 *
 */

public interface TransactionRepository {

    int create(Transaction transaction) throws CloneNotSupportedException;

    int update(Transaction transaction);

    int delete(Transaction transaction);

    Transaction findByXid(TransactionXid xid);

    List<Transaction> findAllUnmodifiedSince(Date date);
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/common/MethodRole.java
================================================
package io.tyloo.common;

/*
 * ɫ
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 15:27 2019/4/15
 *
 */
public enum MethodRole {

    /**
     * 
     */
    ROOT,

    /**
     * ṩ
     */
    PROVIDER,

    /**
     * 
     */
    NORMAL
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/common/TransactionType.java
================================================
package io.tyloo.common;

/*
 * 
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 15:28 2019/4/17
 *
 */

public enum TransactionType {

    /**
     * :1.
     */
    ROOT(1),

    /**
     * ֧:2.
     */
    BRANCH(2);

    int id;

    TransactionType(int id) {
        this.id = id;
    }

    public static TransactionType valueOf(int id) {
        switch (id) {
            case 1:
                return ROOT;
            case 2:
                return BRANCH;
            default:
                return null;
        }
    }

    public int getId() {
        return id;
    }

}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/context/MethodTransactionContextEditor.java
================================================
package io.tyloo.context;

import io.tyloo.api.TransactionContext;
import io.tyloo.api.TransactionContextEditor;
import io.tyloo.utils.TylooMethodUtils;

import java.lang.reflect.Method;

/*
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 16:42 2019/4/16
 *
 */

@Deprecated
public class MethodTransactionContextEditor implements TransactionContextEditor {

    @Override
    public TransactionContext get(Object target, Method method, Object[] args) {
        int position = TylooMethodUtils.getTransactionContextParamPosition(method.getParameterTypes());

        if (position >= 0) {
            return (TransactionContext) args[position];
        }

        return null;
    }

    @Override
    public void set(TransactionContext transactionContext, Object target, Method method, Object[] args) {

        int position = TylooMethodUtils.getTransactionContextParamPosition(method.getParameterTypes());
        if (position >= 0) {
            args[position] = transactionContext;
        }
    }
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/interceptor/TylooCoordinatorAspect.java
================================================
package io.tyloo.interceptor;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

/*
 * ԴЭӦ
 * ͨ@Pointcut + @Around ע⣬ö @Tyloo עķ
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 18:48 2019/4/22
 *
 */

@Aspect
public abstract class TylooCoordinatorAspect {

    private TylooCoordinatorInterceptor tylooCoordinatorInterceptor;

    @Pointcut("@annotation(io.tyloo.api.Tyloo)")
    public void transactionContextCall() {

    }

    @Around("transactionContextCall()")
    public Object interceptTransactionContextMethod(ProceedingJoinPoint pjp) throws Throwable {
        return tylooCoordinatorInterceptor.interceptTransactionContextMethod(pjp);
    }

    public void setTylooCoordinatorInterceptor(TylooCoordinatorInterceptor tylooCoordinatorInterceptor) {
        this.tylooCoordinatorInterceptor = tylooCoordinatorInterceptor;
    }

    public abstract int getOrder();
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/interceptor/TylooCoordinatorInterceptor.java
================================================
package io.tyloo.interceptor;

import io.tyloo.InvocationContext;
import io.tyloo.Participant;
import io.tyloo.Transaction;
import io.tyloo.TransactionManager;
import io.tyloo.api.TransactionContext;
import io.tyloo.api.TransactionStatus;
import io.tyloo.api.TransactionXid;
import io.tyloo.api.Tyloo;
import io.tyloo.support.FactoryBuilder;
import io.tyloo.utils.ReflectionUtils;
import io.tyloo.utils.TylooMethodUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;

import java.lang.reflect.Method;

/*
 * ԴЭ
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 15:35 2019/4/23
 *
 */


public class TylooCoordinatorInterceptor {

    private TransactionManager transactionManager;

    public void setTransactionManager(TransactionManager transactionManager) {
        this.transactionManager = transactionManager;
    }

    public Object interceptTransactionContextMethod(ProceedingJoinPoint pjp) throws Throwable {

        Transaction transaction = transactionManager.getCurrentTransaction();
        if (transaction != null) {
            switch (transaction.getStatus()) {
                case TRYING:
                    enlistParticipant(pjp);
                    break;
                case CONFIRMING:
                    break;
                case CANCELLING:
                    break;
                default:
                    throw new IllegalStateException("Unexpected value: " + transaction.getStatus());
            }
        }

        return pjp.proceed(pjp.getArgs());
    }

    /**
     * ߣ Try ׶α
     *
     * @param pjp
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    private void enlistParticipant(ProceedingJoinPoint pjp) throws IllegalAccessException, InstantiationException, CloneNotSupportedException {

        Method method = TylooMethodUtils.getTylooMethod(pjp);
        if (method == null) {
            throw new RuntimeException(String.format("join point not found method, point is : %s", pjp.getSignature().getName()));
        }
        Tyloo tyloo = method.getAnnotation(Tyloo.class);

        String confirmMethodName = tyloo.confirmMethod();
        String cancelMethodName = tyloo.cancelMethod();

        Transaction transaction = transactionManager.getCurrentTransaction();
        TransactionXid xid = new TransactionXid(transaction.getXid().getGlobalTransactionId());

        if (FactoryBuilder.factoryOf(tyloo.transactionContextEditor()).getInstance().get(pjp.getTarget(), method, pjp.getArgs()) == null) {
            FactoryBuilder.factoryOf(tyloo.transactionContextEditor()).getInstance().set(new TransactionContext(xid, TransactionStatus.TRYING.getId()), pjp.getTarget(), ((MethodSignature) pjp.getSignature()).getMethod(), pjp.getArgs());
        }

        Class targetClass = ReflectionUtils.getDeclaringType(pjp.getTarget().getClass(), method.getName(), method.getParameterTypes());

        InvocationContext confirmInvocation = new InvocationContext(targetClass,
                confirmMethodName,
                method.getParameterTypes(), pjp.getArgs());

        InvocationContext cancelInvocation = new InvocationContext(targetClass,
                cancelMethodName,
                method.getParameterTypes(), pjp.getArgs());

        Participant participant = new Participant(
                xid,
                confirmInvocation,
                cancelInvocation,
                tyloo.transactionContextEditor());
        transactionManager.enlistParticipant(participant);

    }


}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/interceptor/TylooMethodContext.java
================================================
package io.tyloo.interceptor;

import io.tyloo.api.Propagation;
import io.tyloo.api.TransactionContext;
import io.tyloo.api.Tyloo;
import io.tyloo.api.UniqueIdentity;
import io.tyloo.common.MethodRole;
import io.tyloo.support.FactoryBuilder;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/*
 * עⷽ
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 15:33 2019/4/24
 *
 */
public class TylooMethodContext {

    /**
     * 
     */
    private ProceedingJoinPoint pjp = null;

    /**
     * עⷽ
     */
    private Method method = null;

    /**
     * ע
     */
    private Tyloo tyloo = null;

    /**
     * 
     */
    private Propagation propagation = null;

    /**
     * 
     */
    private TransactionContext transactionContext = null;

    TylooMethodContext(ProceedingJoinPoint pjp) {
        this.pjp = pjp;
        this.method = getTylooMethod();
        assert method != null;
        this.tyloo = method.getAnnotation(Tyloo.class);
        this.propagation = tyloo.propagation();
        this.transactionContext = FactoryBuilder.factoryOf(tyloo.transactionContextEditor()).getInstance().get(pjp.getTarget(), method, pjp.getArgs());

    }

    public Tyloo getAnnotation() {
        return tyloo;
    }

    public Propagation getPropagation() {
        return propagation;
    }

    public TransactionContext getTransactionContext() {
        return transactionContext;
    }

    public Method getMethod() {
        return method;
    }

    /**
     * ȡΨһʶ
     *
     * @return
     */
    public Object getUniqueIdentity() {
        Annotation[][] annotations = this.getMethod().getParameterAnnotations();

        for (int i = 0; i < annotations.length; i++) {
            for (Annotation annotation : annotations[i]) {
                if (annotation.annotationType().equals(UniqueIdentity.class)) {

                    Object[] params = pjp.getArgs();

                    return params[i];
                }
            }
        }

        return null;
    }

    /**
     * ȡעⷽ
     *
     * @return
     */
    private Method getTylooMethod() {
        Method method = ((MethodSignature) (pjp.getSignature())).getMethod();

        if (method.getAnnotation(Tyloo.class) == null) {
            try {
                method = pjp.getTarget().getClass().getMethod(method.getName(), method.getParameterTypes());
            } catch (NoSuchMethodException e) {
                return null;
            }
        }
        return method;
    }

    /**
     * ͨ÷񴫲ȡ
     *
     * @param isTransactionActive
     * @return
     */
    public MethodRole getMethodRole(boolean isTransactionActive) {
        if ((propagation.equals(Propagation.REQUIRED) && !isTransactionActive && transactionContext == null) ||
                propagation.equals(Propagation.REQUIRES_NEW)) {
            return MethodRole.ROOT;
        } else if ((propagation.equals(Propagation.REQUIRED) || propagation.equals(Propagation.MANDATORY)) && !isTransactionActive && transactionContext != null) {
            return MethodRole.PROVIDER;
        } else {
            return MethodRole.NORMAL;
        }
    }


    public Object proceed() throws Throwable {
        return this.pjp.proceed();
    }
}

================================================
FILE: tyloo-core/src/main/java/io/tyloo/interceptor/TylooTransactionAspect.java
================================================
package io.tyloo.interceptor;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

/*
 * ɲӦ
 * ͨ@Pointcut + @Around ע⣬ö @Tyloo עķ
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 15:14 2019/4/26
 *
 */
@Aspect
public abstract class TylooTransactionAspect {

    private TylooTransactionInterceptor tylooTransactionInterceptor;

    public void setTylooTransactionInterceptor(TylooTransactionInterceptor tylooTransactionInterceptor) {
        this.tylooTransactionInterceptor = tylooTransactionInterceptor;
    }

    @Pointcut("@annotation(io.tyloo.api.Tyloo)")
    public void tylooService() {

    }

    @Around("tylooService()")
    public Object interceptTylooMethod(ProceedingJoinPoint pjp) throws Throwable {

        return tylooTransactionInterceptor.interceptTylooMethod(pjp);
    }

    public abstract int getOrder();
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/interceptor/TylooTransactionInterceptor.java
================================================
package io.tyloo.interceptor;

import com.alibaba.fastjson.JSON;
import io.tyloo.NoExistedTransactionException;
import io.tyloo.SystemException;
import io.tyloo.Transaction;
import io.tyloo.TransactionManager;
import io.tyloo.api.TransactionStatus;
import io.tyloo.utils.ReflectionUtils;
import io.tyloo.utils.TransactionUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/*
 * ɲ
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 15:18 2019/4/23
 *
 */
public class TylooTransactionInterceptor {

    static final Logger logger = Logger.getLogger(TylooTransactionInterceptor.class.getSimpleName());
    private final Set<Class<? extends Exception>> delayCancelExceptions = new HashSet<>();
    private TransactionManager transactionManager;

    /**
     * .
     *
     * @param transactionManager
     */
    public void setTransactionManager(TransactionManager transactionManager) {
        this.transactionManager = transactionManager;
    }

    public void setDelayCancelExceptions(Set<Class<? extends Exception>> delayCancelExceptions) {
        this.delayCancelExceptions.addAll(delayCancelExceptions);
    }

    /**
     * ز.
     *
     * @param pjp
     * @throws Throwable
     */
    public Object interceptTylooMethod(ProceedingJoinPoint pjp) throws Throwable {

        TylooMethodContext tylooMethodContext = new TylooMethodContext(pjp);
        boolean isTransactionActive = transactionManager.isTransactionActive();
        if (!TransactionUtils.isLegalTransactionContext(isTransactionActive, tylooMethodContext)) {
            throw new SystemException("no active tyloo transaction while propagation is mandatory for method " + tylooMethodContext.getMethod().getName());
        }

        switch (tylooMethodContext.getMethodRole(isTransactionActive)) {
            case ROOT:
                return rootMethodProceed(tylooMethodContext);
            case PROVIDER:
                return providerMethodProceed(tylooMethodContext);
            default:
                return pjp.proceed();
        }
    }

    /**
     * 񷽷Ĵ.
     *
     * @param tylooMethodContext
     * @throws Throwable
     */
    private Object rootMethodProceed(TylooMethodContext tylooMethodContext) throws Throwable {

        Object returnValue = null;
        Transaction transaction = null;

        boolean asyncConfirm = tylooMethodContext.getAnnotation().asyncConfirm();
        boolean asyncCancel = tylooMethodContext.getAnnotation().asyncCancel();

        Set<Class<? extends Exception>> allDelayCancelExceptions = new HashSet<>();
        allDelayCancelExceptions.addAll(this.delayCancelExceptions);
        allDelayCancelExceptions.addAll(Arrays.asList(tylooMethodContext.getAnnotation().delayCancelExceptions()));

        try {
            transaction = transactionManager.begin(tylooMethodContext.getUniqueIdentity());
            try {
                returnValue = tylooMethodContext.proceed();
            } catch (Throwable tryingException) {
                if (!isDelayCancelException(tryingException, allDelayCancelExceptions)) {
                    logger.warn(String.format("tyloo transaction trying failed. transaction content:%s", JSON.toJSONString(transaction)), tryingException);
                    transactionManager.rollback(asyncCancel);
                }
                throw tryingException;
            }
            transactionManager.commit(asyncConfirm);
        } finally {
            transactionManager.cleanAfterCompletion(transaction);
        }
        return returnValue;
    }

    /**
     * ṩ񷽷.
     * ״̬ CONFIRMING / CANCELLING öӦ
     *
     * @param tylooMethodContext
     * @throws Throwable
     */
    private Object providerMethodProceed(TylooMethodContext tylooMethodContext) throws Throwable {

        Transaction transaction = null;
        boolean asyncConfirm = tylooMethodContext.getAnnotation().asyncConfirm();
        boolean asyncCancel = tylooMethodContext.getAnnotation().asyncCancel();

        try {
            switch (TransactionStatus.valueOf(tylooMethodContext.getTransactionContext().getStatus())) {
                case TRYING:
                    transaction = transactionManager.propagationNewBegin(tylooMethodContext.getTransactionContext());
                    return tylooMethodContext.proceed();
                case CONFIRMING:
                    try {
                        transaction = transactionManager.propagationExistBegin(tylooMethodContext.getTransactionContext());
                        transactionManager.commit(asyncConfirm);
                    } catch (NoExistedTransactionException excepton) {
                        //the transaction has been commit,ignore it.
                    }
                    break;
                case CANCELLING:

                    try {
                        transaction = transactionManager.propagationExistBegin(tylooMethodContext.getTransactionContext());
                        transactionManager.rollback(asyncCancel);
                    } catch (NoExistedTransactionException exception) {
                        //the transaction has been rollback,ignore it.
                    }
                    break;
                default:
                    throw new IllegalStateException("Unexpected value: " + TransactionStatus.valueOf(tylooMethodContext.getTransactionContext().getStatus()));
            }

        } finally {
            transactionManager.cleanAfterCompletion(transaction);
        }
        Method method = tylooMethodContext.getMethod();
        return ReflectionUtils.getNullValue(method.getReturnType());
    }

    private boolean isDelayCancelException(Throwable throwable, Set<Class<? extends Exception>> delayCancelExceptions) {

        if (delayCancelExceptions != null) {
            for (Class delayCancelException : delayCancelExceptions) {
                Throwable rootCause = ExceptionUtils.getRootCause(throwable);
                if (!throwable.getClass().isAssignableFrom(delayCancelException)) {
                    if ((rootCause != null) && rootCause.getClass().isAssignableFrom(delayCancelException)) {
                        return true;
                    }
                } else {
                    return true;
                }
            }
        }
        return false;
    }
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/recover/TylooRecoverConfiguration.java
================================================
package io.tyloo.recover;

import java.util.Set;

/*
 * ָýӿ.
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 18:50 2019/5/1
 *
 */

public interface TylooRecoverConfiguration {

    /**
     * ȡԴ
     *
     * @return
     */
    int getMaxRetryCount();

    /**
     * ȡҪִָijʱ.
     *
     * @return
     */
    int getRecoverDuration();

    /**
     * ȡʱʽ.
     *
     * @return
     */
    String getCronExpression();

    /**
     * ӳȡ쳣
     *
     * @return
     */
    Set<Class<? extends Exception>> getDelayCancelExceptions();

    void setDelayCancelExceptions(Set<Class<? extends Exception>> delayRecoverExceptions);

    int getAsyncTerminateThreadCorePoolSize();

    int getAsyncTerminateThreadMaxPoolSize();

    int getAsyncTerminateThreadWorkQueueSize();
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/recover/TylooTransactionRecovery.java
================================================
package io.tyloo.recover;

import com.alibaba.fastjson.JSON;
import io.tyloo.OptimisticLockException;
import io.tyloo.Transaction;
import io.tyloo.TransactionRepository;
import io.tyloo.api.TransactionStatus;
import io.tyloo.common.TransactionType;
import io.tyloo.support.TransactionConfigurator;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.log4j.Logger;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

/*
 *
 * ָ
 *
 * Ϣ־ûⲿĴ洢⣩С洢ָĻͨȡⲿ洢е쳣񣬶ʱᰴһƵʶԣֱɻ򳬹Դ
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 18:51 2019/5/2
 *
 */
public class TylooTransactionRecovery {

    static final Logger logger = Logger.getLogger(TylooTransactionRecovery.class.getSimpleName());

    /**
     * TCC.
     */
    private TransactionConfigurator transactionConfigurator;

    /**
     * ָ(RecoverScheduledJobʱ).
     */
    public void startRecover() throws CloneNotSupportedException {

        List<Transaction> transactions = loadErrorTransactions();
        recoverErrorTransactions(transactions);
    }

    /**
     * ҳִдϢ
     *
     * @return
     */
    private List<Transaction> loadErrorTransactions() {
        long currentTimeInMillis = Calendar.getInstance().getTimeInMillis();
        TransactionRepository transactionRepository = transactionConfigurator.getTransactionRepository();
        TylooRecoverConfiguration tylooRecoverConfiguration = transactionConfigurator.getTylooRecoverConfiguration();
        return transactionRepository.findAllUnmodifiedSince(new Date(currentTimeInMillis - tylooRecoverConfiguration.getRecoverDuration() * 1000));
    }

    /**
     * ָ.
     *
     * @param transactions
     */
    private void recoverErrorTransactions(List<Transaction> transactions) throws CloneNotSupportedException {

        for (Transaction transaction : transactions) {
            //ȽԴ
            if (transaction.getRetriedCount() > transactionConfigurator.getTylooRecoverConfiguration().getMaxRetryCount()) {
                logger.error(String.format("recover failed with max retry count,will not try again. txid:%s, status:%s,retried count:%d,transaction content:%s", transaction.getXid(), transaction.getStatus().getId(), transaction.getRetriedCount(), JSON.toJSONString(transaction)));
                continue;
            }

            //ǰǷ֧ʱ
            if (transaction.getTransactionType().equals(TransactionType.BRANCH)
                    && (transaction.getCreateTime().getTime() +
                    transactionConfigurator.getTylooRecoverConfiguration().getMaxRetryCount() *
                            transactionConfigurator.getTylooRecoverConfiguration().getRecoverDuration() * 1000
                    > System.currentTimeMillis())) {
                continue;
            }

            try {
                transaction.addRetriedCount();
                // CONFIRMING(2)״̬ǰִ
                if (transaction.getStatus().equals(TransactionStatus.CONFIRMING)) {
                    transaction.changeStatus(TransactionStatus.CONFIRMING);
                    transactionConfigurator.getTransactionRepository().update(transaction);
                    transaction.commit();
                    transactionConfigurator.getTransactionRepository().delete(transaction);

                } else if (transaction.getStatus().equals(TransactionStatus.CANCELLING)
                        || transaction.getTransactionType().equals(TransactionType.ROOT)) {
                    // ״̬ΪCANCELLING(3)Ȼִлع
                    transaction.changeStatus(TransactionStatus.CANCELLING);
                    transactionConfigurator.getTransactionRepository().update(transaction);
                    transaction.rollback();
                    // £ʱû־ֱɾ
                    transactionConfigurator.getTransactionRepository().delete(transaction);
                }

            } catch (Throwable throwable) {
                if (throwable instanceof OptimisticLockException
                        || ExceptionUtils.getRootCause(throwable) instanceof OptimisticLockException) {
                    logger.warn(String.format("optimisticLockException happened while recover. txid:%s, status:%s,retried count:%d,transaction content:%s", transaction.getXid(), transaction.getStatus().getId(), transaction.getRetriedCount(), JSON.toJSONString(transaction)), throwable);
                } else {
                    logger.error(String.format("recover failed, txid:%s, status:%s,retried count:%d,transaction content:%s", transaction.getXid(), transaction.getStatus().getId(), transaction.getRetriedCount(), JSON.toJSONString(transaction)), throwable);
                }
            }
        }
    }

    public void setTransactionConfigurator(TransactionConfigurator transactionConfigurator) {
        this.transactionConfigurator = transactionConfigurator;
    }
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/repository/CachableTransactionRepository.java
================================================
package io.tyloo.repository;


import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import io.tyloo.ConcurrentTransactionException;
import io.tyloo.OptimisticLockException;
import io.tyloo.Transaction;
import io.tyloo.TransactionRepository;
import io.tyloo.api.TransactionXid;

import javax.transaction.xa.Xid;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/*
 *
 * 
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:08 2019/5/12
 *
 */
public abstract class CachableTransactionRepository implements TransactionRepository {

    /**
     * ʱ(Ϊλ)
     */
    private int expireDuration = 120;
    /**
     * ־¼<Xid, Transaction>
     */
    private final Cache<Xid, Transaction> transactionXidTylooTransactionCache;

    public CachableTransactionRepository() {
        transactionXidTylooTransactionCache = CacheBuilder.newBuilder().expireAfterAccess(expireDuration, TimeUnit.SECONDS).maximumSize(1000).build();
    }

    /**
     * ־¼
     */
    @Override
    public int create(Transaction transaction) throws CloneNotSupportedException {
        int result = doCreate(transaction);
        if (result > 0) {
            putToCache(transaction);
        } else {
            throw new ConcurrentTransactionException("transaction xid duplicated. xid:" + transaction.getXid().toString());
        }

        return result;
    }

    /**
     * ־¼
     */
    @Override
    public int update(Transaction transaction) {
        int result = 0;

        try {
            result = doUpdate(transaction);
            if (result > 0) {
                putToCache(transaction);
            } else {
                throw new OptimisticLockException();
            }
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        } finally {
            if (result <= 0) {
                removeFromCache(transaction);
            }
        }

        return result;
    }

    /**
     * ɾ־¼
     */
    @Override
    public int delete(Transaction transaction) {
        int result = 0;

        try {
            result = doDelete(transaction);

        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        } finally {
            removeFromCache(transaction);
        }
        return result;
    }

    /**
     * xid־¼.
     *
     * @param transactionXid
     * @return
     */
    @Override
    public Transaction findByXid(TransactionXid transactionXid) {
        Transaction transaction = findFromCache(transactionXid);

        if (transaction == null) {
            transaction = doFindOne(transactionXid);
            if (transaction != null) {
                putToCache(transaction);
            }
        }

        return transaction;
    }

    /**
     * ҳδ־ijһʱ㿪ʼ.
     *
     * @return
     */
    @Override
    public List<Transaction> findAllUnmodifiedSince(Date date) {

        List<Transaction> transactions = doFindAllUnmodifiedSince(date);
        for (Transaction transaction : transactions) {
            putToCache(transaction);
        }
        return transactions;
    }

    /**
     * 뻺.
     *
     * @param transaction
     */
    protected void putToCache(Transaction transaction) {
        transactionXidTylooTransactionCache.put(transaction.getXid(), transaction);
    }

    /**
     * ӻɾ.
     *
     * @param transaction
     */
    protected void removeFromCache(Transaction transaction) {
        transactionXidTylooTransactionCache.invalidate(transaction.getXid());
    }

    /**
     * ӻв.
     *
     * @param transactionXid
     * @return
     */
    protected Transaction findFromCache(TransactionXid transactionXid) {
        return transactionXidTylooTransactionCache.getIfPresent(transactionXid);
    }

    public void setExpireDuration(int durationInSeconds) {
        this.expireDuration = durationInSeconds;
    }

    /**
     * ־¼
     *
     * @param transaction
     * @return
     */
    protected abstract int doCreate(Transaction transaction) throws CloneNotSupportedException;

    protected abstract int doUpdate(Transaction transaction) throws CloneNotSupportedException;

    protected abstract int doDelete(Transaction transaction) throws CloneNotSupportedException;

    protected abstract Transaction doFindOne(Xid xid);

    protected abstract List<Transaction> doFindAllUnmodifiedSince(Date date);
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/repository/FileSystemTransactionRepository.java
================================================
package io.tyloo.repository;

import io.tyloo.Transaction;
import io.tyloo.repository.helper.TransactionSerializer;
import io.tyloo.serializer.KryoPoolSerializer;
import io.tyloo.serializer.ObjectSerializer;

import javax.transaction.xa.Xid;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/*
 * ļϵͳ
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:22 2019/5/14
 *
 */
public class FileSystemTransactionRepository extends CachableTransactionRepository {

    private String rootPath = "/tcc";

    private volatile boolean initialized;

    private ObjectSerializer serializer = new KryoPoolSerializer();

    public void setSerializer(ObjectSerializer serializer) {
        this.serializer = serializer;
    }

    public void setRootPath(String rootPath) {
        this.rootPath = rootPath;
    }

    @Override
    protected int doCreate(Transaction transaction) throws CloneNotSupportedException {
        return createFile(transaction);
    }

    @Override
    protected int doUpdate(Transaction transaction) throws CloneNotSupportedException {

        transaction.updateVersion();
        transaction.updateTime();

        writeFile(transaction);
        return 1;
    }

    @Override
    protected int doDelete(Transaction transaction) throws CloneNotSupportedException {

        String fullFileName = getFullFileName(transaction.getXid());
        File file = new File(fullFileName);
        if (file.exists()) {
            return file.delete() ? 1 : 0;
        }
        return 1;
    }

    @Override
    protected Transaction doFindOne(Xid xid) {

        String fullFileName = getFullFileName(xid);
        File file = new File(fullFileName);

        if (file.exists()) {
            return readTransaction(file);
        }

        return null;
    }

    @Override
    protected List<Transaction> doFindAllUnmodifiedSince(Date date) {

        List<Transaction> allTransactions = doFindAll();

        List<Transaction> allUnmodifiedSince = new ArrayList<Transaction>();

        for (Transaction transaction : allTransactions) {
            if (transaction.getLastUpdateTime().compareTo(date) < 0) {
                allUnmodifiedSince.add(transaction);
            }
        }

        return allUnmodifiedSince;
    }


    protected List<Transaction> doFindAll() {

        List<Transaction> transactions = new ArrayList<Transaction>();
        File path = new File(rootPath);
        File[] files = path.listFiles();

        for (File file : files) {
            Transaction transaction = readTransaction(file);
            transactions.add(transaction);
        }

        return transactions;
    }

    private String getFullFileName(Xid xid) {
        return String.format("%s/%s", rootPath, xid);
    }

    private void makeDirIfNecessary() {
        if (!initialized) {
            synchronized (FileSystemTransactionRepository.class) {
                if (!initialized) {
                    File rootPathFile = new File(rootPath);
                    if (!rootPathFile.exists()) {

                        boolean result = rootPathFile.mkdir();

                        if (!result) {
                            throw new TransactionIOException("cannot create root path, the path to create is:" + rootPath);
                        }

                        initialized = true;
                    } else if (!rootPathFile.isDirectory()) {
                        throw new TransactionIOException("rootPath is not directory");
                    }
                }
            }
        }
    }


    private int createFile(Transaction transaction) throws CloneNotSupportedException {
        makeDirIfNecessary();

        String filePath = getFullFileName(transaction.getXid());

        FileChannel channel = null;
        RandomAccessFile raf = null;
        File file = null;

        byte[] content = TransactionSerializer.serialize(serializer, transaction);

        try {

            file = new File(filePath);

            boolean result = file.createNewFile();

            if (!result) {
                return 0;
            }

            raf = new RandomAccessFile(file, "rw");
            channel = raf.getChannel();
            ByteBuffer buffer = ByteBuffer.allocate(content.length);
            buffer.put(content);
            buffer.flip();

            while (buffer.hasRemaining()) {
                channel.write(buffer);
            }

            channel.force(true);

            return 1;

        } catch (FileNotFoundException e) {
            throw new TransactionIOException(e);
        } catch (IOException e) {
            throw new TransactionIOException(e);
        } finally {
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (IOException e) {
                    throw new TransactionIOException(e);
                }
            }
        }
    }

    private void writeFile(Transaction transaction) throws CloneNotSupportedException {

        makeDirIfNecessary();

        String filePath = getFullFileName(transaction.getXid());

        FileChannel channel = null;
        RandomAccessFile raf = null;

        byte[] content = TransactionSerializer.serialize(serializer, transaction);

        try {

            raf = new RandomAccessFile(filePath, "rw");
            channel = raf.getChannel();
            ByteBuffer buffer = ByteBuffer.allocate(content.length);
            buffer.put(content);
            buffer.flip();

            while (buffer.hasRemaining()) {
                channel.write(buffer);
            }

            channel.force(true);

        } catch (Exception e) {
            throw new TransactionIOException(e);
        } finally {
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (IOException e) {
                    throw new TransactionIOException(e);
                }
            }
        }
    }

    private Transaction readTransaction(File file) {

        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);

            byte[] content = new byte[(int) file.length()];

            fis.read(content);

            if (content != null) {
                return TransactionSerializer.deserialize(serializer, content);
            }
        } catch (Exception e) {
            throw new TransactionIOException(e);
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    throw new TransactionIOException(e);
                }
            }
        }

        return null;
    }
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/repository/JdbcTransactionRepository.java
================================================
package io.tyloo.repository;


import io.tyloo.Transaction;
import io.tyloo.api.TransactionStatus;
import io.tyloo.serializer.KryoPoolSerializer;
import io.tyloo.serializer.ObjectSerializer;
import io.tyloo.utils.CollectionUtils;
import io.tyloo.utils.StringUtils;

import javax.sql.DataSource;
import javax.transaction.xa.Xid;
import java.sql.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/*
 *
 * JDBC⣨Ӧ÷ʵעԴ
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:26 2019/5/13
 *
 */
public class JdbcTransactionRepository extends CachableTransactionRepository {

    private String domain;

    private String tbSuffix;

    private DataSource dataSource;

    private ObjectSerializer<Transaction> serializer = new KryoPoolSerializer();

    public String getDomain() {
        return domain;
    }

    public void setDomain(String domain) {
        this.domain = domain;
    }

    public String getTbSuffix() {
        return tbSuffix;
    }

    public void setTbSuffix(String tbSuffix) {
        this.tbSuffix = tbSuffix;
    }

    public void setSerializer(ObjectSerializer<Transaction> serializer) {
        this.serializer = serializer;
    }

    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Override
    protected int doCreate(Transaction transaction) {

        Connection connection = null;
        PreparedStatement stmt = null;

        try {
            connection = this.getConnection();

            StringBuilder builder = new StringBuilder();
            builder.append("INSERT INTO " + getTableName() +
                    "(GLOBAL_TX_ID,BRANCH_QUALIFIER,TRANSACTION_TYPE,CONTENT,STATUS,RETRIED_COUNT,CREATE_TIME,LAST_UPDATE_TIME,VERSION");
            builder.append(StringUtils.isNotEmpty(domain) ? ",DOMAIN ) VALUES (?,?,?,?,?,?,?,?,?,?)" : ") VALUES (?,?,?,?,?,?,?,?,?)");

            stmt = connection.prepareStatement(builder.toString());

            stmt.setBytes(1, transaction.getXid().getGlobalTransactionId());
            stmt.setBytes(2, transaction.getXid().getBranchQualifier());
            stmt.setInt(3, transaction.getTransactionType().getId());
            stmt.setBytes(4, serializer.serialize(transaction));
            stmt.setInt(5, transaction.getStatus().getId());
            stmt.setInt(6, transaction.getRetriedCount());
            stmt.setTimestamp(7, new java.sql.Timestamp(transaction.getCreateTime().getTime()));
            stmt.setTimestamp(8, new java.sql.Timestamp(transaction.getLastUpdateTime().getTime()));
            stmt.setLong(9, transaction.getVersion());

            if (StringUtils.isNotEmpty(domain)) {
                stmt.setString(10, domain);
            }

            stmt.executeUpdate();
            return 1;
        } catch (SQLException e) {
            if (e instanceof SQLIntegrityConstraintViolationException) {
                return 0;
            } else {
                throw new TransactionIOException(e);
            }
        } catch (Throwable throwable) {
            throw new TransactionIOException(throwable);
        } finally {
            closeStatement(stmt);
            this.releaseConnection(connection);
        }
    }

    @Override
    protected int doUpdate(Transaction transaction) {
        Connection connection = null;
        PreparedStatement stmt = null;

        java.util.Date lastUpdateTime = transaction.getLastUpdateTime();
        long currentVersion = transaction.getVersion();

        transaction.updateTime();
        transaction.updateVersion();

        try {
            connection = this.getConnection();

            StringBuilder builder = new StringBuilder();
            builder.append("UPDATE " + getTableName() + " SET " +
                    "CONTENT = ?,STATUS = ?,LAST_UPDATE_TIME = ?, RETRIED_COUNT = ?,VERSION = VERSION+1 WHERE GLOBAL_TX_ID = ? AND BRANCH_QUALIFIER = ? AND VERSION = ?");

            builder.append(StringUtils.isNotEmpty(domain) ? " AND DOMAIN = ?" : "");

            stmt = connection.prepareStatement(builder.toString());

            stmt.setBytes(1, serializer.serialize(transaction));
            stmt.setInt(2, transaction.getStatus().getId());
            stmt.setTimestamp(3, new Timestamp(transaction.getLastUpdateTime().getTime()));

            stmt.setInt(4, transaction.getRetriedCount());
            stmt.setBytes(5, transaction.getXid().getGlobalTransactionId());
            stmt.setBytes(6, transaction.getXid().getBranchQualifier());
            stmt.setLong(7, currentVersion);

            if (StringUtils.isNotEmpty(domain)) {
                stmt.setString(8, domain);
            }

            int result = stmt.executeUpdate();

            return result;

        } catch (Throwable e) {
            transaction.setLastUpdateTime(lastUpdateTime);
            transaction.setVersion(currentVersion);
            throw new TransactionIOException(e);
        } finally {
            closeStatement(stmt);
            this.releaseConnection(connection);
        }
    }

    @Override
    protected int doDelete(Transaction transaction) {
        Connection connection = null;
        PreparedStatement stmt = null;

        try {
            connection = this.getConnection();
            String builder = "DELETE FROM " + getTableName() +
                    " WHERE GLOBAL_TX_ID = ? AND BRANCH_QUALIFIER = ?" +
                    (StringUtils.isNotEmpty(domain) ? " AND DOMAIN = ?" : "");
            stmt = connection.prepareStatement(builder);

            stmt.setBytes(1, transaction.getXid().getGlobalTransactionId());
            stmt.setBytes(2, transaction.getXid().getBranchQualifier());

            if (StringUtils.isNotEmpty(domain)) {
                stmt.setString(3, domain);
            }
            return stmt.executeUpdate();

        } catch (SQLException e) {
            throw new TransactionIOException(e);
        } finally {
            closeStatement(stmt);
            this.releaseConnection(connection);
        }
    }

    @Override
    protected Transaction doFindOne(Xid xid) {

        List<Transaction> transactions = doFind(Arrays.asList(xid));

        if (!CollectionUtils.isEmpty(transactions)) {
            return transactions.get(0);
        }
        return null;
    }

    @Override
    protected List<Transaction> doFindAllUnmodifiedSince(java.util.Date date) {

        List<Transaction> transactions = new ArrayList<Transaction>();

        Connection connection = null;
        PreparedStatement stmt = null;

        try {
            connection = this.getConnection();

            StringBuilder builder = new StringBuilder();

            builder.append("SELECT GLOBAL_TX_ID, BRANCH_QUALIFIER, CONTENT,STATUS,TRANSACTION_TYPE,CREATE_TIME,LAST_UPDATE_TIME,RETRIED_COUNT,VERSION");
            builder.append(StringUtils.isNotEmpty(domain) ? ",DOMAIN" : "");
            builder.append("  FROM " + getTableName() + " WHERE LAST_UPDATE_TIME < ?");
            builder.append(" AND IS_DELETE = 0 ");
            builder.append(StringUtils.isNotEmpty(domain) ? " AND DOMAIN = ?" : "");

            stmt = connection.prepareStatement(builder.toString());

            stmt.setTimestamp(1, new Timestamp(date.getTime()));

            if (StringUtils.isNotEmpty(domain)) {
                stmt.setString(2, domain);
            }

            ResultSet resultSet = stmt.executeQuery();

            this.constructTransactions(resultSet, transactions);
        } catch (Throwable e) {
            throw new TransactionIOException(e);
        } finally {
            closeStatement(stmt);
            this.releaseConnection(connection);
        }

        return transactions;
    }

    protected List<Transaction> doFind(List<Xid> xids) {

        List<Transaction> transactions = new ArrayList<Transaction>();
        if (CollectionUtils.isEmpty(xids)) {
            return transactions;
        }

        Connection connection = null;
        PreparedStatement stmt = null;

        try {
            connection = this.getConnection();

            StringBuilder builder = new StringBuilder();
            builder.append("SELECT GLOBAL_TX_ID, BRANCH_QUALIFIER, CONTENT,STATUS,TRANSACTION_TYPE,CREATE_TIME,LAST_UPDATE_TIME,RETRIED_COUNT,VERSION");
            builder.append(StringUtils.isNotEmpty(domain) ? ",DOMAIN" : "");
            builder.append("  FROM " + getTableName() + " WHERE");

            if (!CollectionUtils.isEmpty(xids)) {
                for (Xid xid : xids) {
                    builder.append(" ( GLOBAL_TX_ID = ? AND BRANCH_QUALIFIER = ? ) OR");
                }

                builder.delete(builder.length() - 2, builder.length());
            }

            builder.append(StringUtils.isNotEmpty(domain) ? " AND DOMAIN = ?" : "");

            stmt = connection.prepareStatement(builder.toString());

            int i = 0;

            for (Xid xid : xids) {
                stmt.setBytes(++i, xid.getGlobalTransactionId());
                stmt.setBytes(++i, xid.getBranchQualifier());
            }

            if (StringUtils.isNotEmpty(domain)) {
                stmt.setString(++i, domain);
            }

            ResultSet resultSet = stmt.executeQuery();

            this.constructTransactions(resultSet, transactions);
        } catch (Throwable e) {
            throw new TransactionIOException(e);
        } finally {
            closeStatement(stmt);
            this.releaseConnection(connection);
        }

        return transactions;
    }

    protected void constructTransactions(ResultSet resultSet, List<Transaction> transactions) throws SQLException {
        while (resultSet.next()) {
            byte[] transactionBytes = resultSet.getBytes(3);
            Transaction transaction = serializer.deserialize(transactionBytes);
            transaction.changeStatus(TransactionStatus.valueOf(resultSet.getInt(4)));
            transaction.setLastUpdateTime(resultSet.getDate(7));
            transaction.setVersion(resultSet.getLong(9));
            transaction.resetRetriedCount(resultSet.getInt(8));
            transactions.add(transaction);
        }
    }


    protected Connection getConnection() {
        try {
            return this.dataSource.getConnection();
        } catch (SQLException e) {
            throw new TransactionIOException(e);
        }
    }

    protected void releaseConnection(Connection con) {
        try {
            if (con != null && !con.isClosed()) {
                con.close();
            }
        } catch (SQLException e) {
            throw new TransactionIOException(e);
        }
    }

    private void closeStatement(Statement stmt) {
        try {
            if (stmt != null && !stmt.isClosed()) {
                stmt.close();
            }
        } catch (Exception ex) {
            throw new TransactionIOException(ex);
        }
    }

    private String getTableName() {
        return StringUtils.isNotEmpty(tbSuffix) ? "TCC_TRANSACTION" + tbSuffix : "TCC_TRANSACTION";
    }
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/repository/RedisTransactionRepository.java
================================================
package io.tyloo.repository;

import io.tyloo.Transaction;
import io.tyloo.repository.helper.ExpandTransactionSerializer;
import io.tyloo.repository.helper.JedisCallback;
import io.tyloo.repository.helper.RedisHelper;
import io.tyloo.serializer.KryoPoolSerializer;
import io.tyloo.serializer.ObjectSerializer;
import org.apache.log4j.Logger;
import redis.clients.jedis.*;

import javax.transaction.xa.Xid;
import java.util.*;

/*
 *
 * Redis
 * JedisRedisٷƼJavaӿ
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:27 2019/5/17
 *
 */
public class RedisTransactionRepository extends CachableTransactionRepository {

    private static final Logger logger = Logger.getLogger(RedisTransactionRepository.class.getSimpleName());

    private JedisPool jedisPool;

    private String keyPrefix = "TCC:";

    private int fetchKeySize = 1000;

    private boolean isSupportScan = true;

    private boolean isForbiddenKeys = false;
    private ObjectSerializer serializer = new KryoPoolSerializer();

    public void setKeyPrefix(String keyPrefix) {
        this.keyPrefix = keyPrefix;
    }

    public void setSerializer(ObjectSerializer serializer) {
        this.serializer = serializer;
    }

    public int getFetchKeySize() {
        return fetchKeySize;
    }

    public void setFetchKeySize(int fetchKeySize) {
        this.fetchKeySize = fetchKeySize;
    }

    public JedisPool getJedisPool() {
        return jedisPool;
    }

    public void setJedisPool(JedisPool jedisPool) {

        this.jedisPool = jedisPool;

        isSupportScan = RedisHelper.isSupportScanCommand(jedisPool.getResource());

        if (!isSupportScan && isForbiddenKeys) {
            throw new RuntimeException("Redis not support 'scan' command, " +
                    "and 'keys' command is forbidden, " +
                    "try update redis version higher than 2.8.0 " +
                    "or set 'isForbiddenKeys' to false");
        }
    }

    public void setSupportScan(boolean isSupportScan) {
        this.isSupportScan = isSupportScan;
    }

    public void setForbiddenKeys(boolean forbiddenKeys) {
        isForbiddenKeys = forbiddenKeys;
    }

    @Override
    protected int doCreate(final Transaction transaction) {

        try {
            Long statusCode = RedisHelper.execute(jedisPool, jedis -> {

                List<byte[]> params = new ArrayList<>();

                for (Map.Entry<byte[], byte[]> entry : ExpandTransactionSerializer.serialize(serializer, transaction).entrySet()) {
                    params.add(entry.getKey());
                    params.add(entry.getValue());
                }

                Object result = jedis.eval("if redis.call('exists', KEYS[1]) == 0 then redis.call('hmset', KEYS[1], unpack(ARGV)); return 1; end; return 0;".getBytes(),
                        Arrays.asList(RedisHelper.getRedisKey(keyPrefix, transaction.getXid())), params);

                return (Long) result;
            });
            return statusCode.intValue();

        } catch (Exception e) {
            throw new TransactionIOException(e);
        }
    }

    @Override
    protected int doUpdate(final Transaction transaction) {

        try {
            Long statusCode = RedisHelper.execute(jedisPool, jedis -> {

                transaction.updateTime();
                transaction.updateVersion();

                List<byte[]> params = new ArrayList<>();

                for (Map.Entry<byte[], byte[]> entry : ExpandTransactionSerializer.serialize(serializer, transaction).entrySet()) {
                    params.add(entry.getKey());
                    params.add(entry.getValue());
                }

                Object result = jedis.eval(String.format("if redis.call('hget',KEYS[1],'VERSION') == '%s' then redis.call('hmset', KEYS[1], unpack(ARGV)); return 1; end; return 0;",
                        transaction.getVersion() - 1).getBytes(),
                        Arrays.asList(RedisHelper.getRedisKey(keyPrefix, transaction.getXid())), params);

                return (Long) result;
            });

            return statusCode.intValue();
        } catch (Exception e) {
            throw new TransactionIOException(e);
        }
    }

    @Override
    protected int doDelete(final Transaction transaction) {
        try {

            Long result = RedisHelper.execute(jedisPool, jedis -> jedis.del(RedisHelper.getRedisKey(keyPrefix, transaction.getXid())));

            return result.intValue();
        } catch (Exception e) {
            throw new TransactionIOException(e);
        }
    }

    @Override
    protected Transaction doFindOne(final Xid xid) {

        try {
            Long startTime = System.currentTimeMillis();
            Map<byte[], byte[]> content = RedisHelper.execute(jedisPool, jedis -> jedis.hgetAll(RedisHelper.getRedisKey(keyPrefix, xid)));
            logger.info("redis find cost time :" + (System.currentTimeMillis() - startTime));

            if (content != null && content.size() > 0) {
                return ExpandTransactionSerializer.deserialize(serializer, content);
            }
            return null;
        } catch (Exception e) {
            throw new TransactionIOException(e);
        }
    }

    @Override
    protected List<Transaction> doFindAllUnmodifiedSince(Date date) {

        List<Transaction> allTransactions = doFindAll();
        List<Transaction> allUnmodifiedSince = new ArrayList<>();

        for (Transaction transaction : allTransactions) {
            if (transaction.getLastUpdateTime().compareTo(date) < 0) {
                allUnmodifiedSince.add(transaction);
            }
        }

        return allUnmodifiedSince;
    }

    //    @Override
    protected List<Transaction> doFindAll() {

        try {
            final Set<byte[]> keys = RedisHelper.execute(jedisPool, jedis -> {
                if (isSupportScan) {
                    List<String> allKeys = new ArrayList<>();
                    String cursor = RedisHelper.SCAN_INIT_CURSOR;
                    ScanParams scanParams = RedisHelper.buildDefaultScanParams(keyPrefix + "*", fetchKeySize);
                    do {
                        ScanResult<String> scanResult = jedis.scan(cursor, scanParams);
                        allKeys.addAll(scanResult.getResult());
                        cursor = scanResult.getStringCursor();
                    } while (!cursor.equals(RedisHelper.SCAN_INIT_CURSOR));

                    Set<byte[]> allKeySet = new HashSet<>();

                    for (String key : allKeys) {
                        allKeySet.add(key.getBytes());
                    }
                    logger.info(String.format("find all key by scan command with pattern:%s allKeySet.size()=%d", keyPrefix + "*", allKeySet.size()));
                    return allKeySet;
                } else {
                    return jedis.keys((keyPrefix + "*").getBytes());
                }

            });


            return RedisHelper.execute(jedisPool, jedis -> {

                Pipeline pipeline = jedis.pipelined();

                for (final byte[] key : keys) {
                    pipeline.hgetAll(key);
                }
                List<Object> result = pipeline.syncAndReturnAll();

                List<Transaction> list = new ArrayList<>();
                for (Object data : result) {
                    if (data != null && ((Map<byte[], byte[]>) data).size() > 0) {
                        list.add(ExpandTransactionSerializer.deserialize(serializer, (Map<byte[], byte[]>) data));
                    }
                }
                return list;
            });

        } catch (Exception e) {
            throw new TransactionIOException(e);
        }
    }
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/repository/TransactionIOException.java
================================================
package io.tyloo.repository;

/*
 *
 * IO쳣
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:27 2019/5/16
 *
 */
public class TransactionIOException extends RuntimeException {

    private static final long serialVersionUID = 6508064607297986329L;

    public TransactionIOException(String message) {
        super(message);
    }

    public TransactionIOException(Throwable e) {
        super(e);
    }
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/repository/helper/ExpandTransactionSerializer.java
================================================
package io.tyloo.repository.helper;

import com.alibaba.fastjson.JSON;
import io.tyloo.SystemException;
import io.tyloo.Transaction;
import io.tyloo.api.TransactionStatus;
import io.tyloo.serializer.ObjectSerializer;
import io.tyloo.utils.ByteUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;

import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;

/*
 *
 * л
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:07 2019/5/4
 *
 */

public class ExpandTransactionSerializer {

    public static Map<byte[], byte[]> serialize(ObjectSerializer serializer, Transaction transaction) throws CloneNotSupportedException {

        Map<byte[], byte[]> map = new HashMap<>();

        map.put("GLOBAL_TX_ID".getBytes(), transaction.getXid().getGlobalTransactionId());
        map.put("BRANCH_QUALIFIER".getBytes(), transaction.getXid().getBranchQualifier());
        map.put("STATUS".getBytes(), ByteUtils.intToBytes(transaction.getStatus().getId()));
        map.put("TRANSACTION_TYPE".getBytes(), ByteUtils.intToBytes(transaction.getTransactionType().getId()));
        map.put("RETRIED_COUNT".getBytes(), ByteUtils.intToBytes(transaction.getRetriedCount()));
        map.put("CREATE_TIME".getBytes(), DateFormatUtils.format(transaction.getCreateTime(), "yyyy-MM-dd HH:mm:ss").getBytes());
        map.put("LAST_UPDATE_TIME".getBytes(), DateFormatUtils.format(transaction.getLastUpdateTime(), "yyyy-MM-dd HH:mm:ss").getBytes());
        map.put("VERSION".getBytes(), ByteUtils.longToBytes(transaction.getVersion()));
        map.put("CONTENT".getBytes(), serializer.serialize(transaction));
        map.put("CONTENT_VIEW".getBytes(), JSON.toJSONString(transaction).getBytes());
        return map;
    }

    public static Transaction deserialize(ObjectSerializer serializer, Map<byte[], byte[]> map1) {

        Map<String, byte[]> propertyMap = new HashMap<>();

        for (Map.Entry<byte[], byte[]> entry : map1.entrySet()) {
            propertyMap.put(new String(entry.getKey()), entry.getValue());
        }

        byte[] content = propertyMap.get("CONTENT");
        Transaction transaction = (Transaction) serializer.deserialize(content);
        transaction.changeStatus(TransactionStatus.valueOf(ByteUtils.bytesToInt(propertyMap.get("STATUS"))));
        transaction.resetRetriedCount(ByteUtils.bytesToInt(propertyMap.get("RETRIED_COUNT")));

        try {
            transaction.setLastUpdateTime(DateUtils.parseDate(new String(propertyMap.get("LAST_UPDATE_TIME")), "yyyy-MM-dd HH:mm:ss"));
        } catch (ParseException e) {
            throw new SystemException(e);
        }

        transaction.setVersion(ByteUtils.bytesToLong(propertyMap.get("VERSION")));
        return transaction;
    }
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/repository/helper/JedisCallback.java
================================================
package io.tyloo.repository.helper;

import redis.clients.jedis.Jedis;

/*
 * Jedisصӿ
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:07 2019/5/4
 *
 */

public interface JedisCallback<T> {

    /**
     * doInJedisΪṩһδװ jedis 󣬿ʹԭ jedis ĸַ
     * @param jedis
     * @return
     */
    public T doInJedis(Jedis jedis) throws CloneNotSupportedException;
}

================================================
FILE: tyloo-core/src/main/java/io/tyloo/repository/helper/RedisHelper.java
================================================
package io.tyloo.repository.helper;

import org.apache.log4j.Logger;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.exceptions.JedisDataException;

import javax.transaction.xa.Xid;

/*
 *
 * Redis
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:07 2019/5/6
 *
 */

public class RedisHelper {

    public static int SCAN_COUNT = 30;
    public static String SCAN_TEST_PATTERN = "*";
    public static String SCAN_INIT_CURSOR = "0";

    private static final Logger logger = Logger.getLogger(RedisHelper.class);

    public static byte[] getRedisKey(String keyPrefix, Xid xid) {
        return (keyPrefix + xid.toString()).getBytes();
    }

    public static byte[] getRedisKey(String keyPrefix, String globalTransactionId, String branchQualifier) {
        return (keyPrefix + globalTransactionId + ":" + branchQualifier).getBytes();
    }

    /**
     * JedisPoolÿJedis
     *  @param <T>
     * @param jedisPool
     * @param callback
     * @return
     */
    public static <T> T execute(JedisPool jedisPool, JedisCallback<T> callback) {
        try (Jedis jedis = jedisPool.getResource()) {
            return callback.doInJedis(jedis);
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * SCAN cursor [MATCH pattern] [COUNT count]
     * $redis-cli scan 0 match key99* count 1000
     * 1) "13912"
     * 2)  1) "key997"
     * 2) "key9906"
     * 3) "key9957"
     * 4) "key9902"
     * 5) "key9971"
     * 6) "key9935"
     * 7) "key9958"
     * 8) "key9928"
     * 9) "key9931"
     * 10) "key9961"
     * 11) "key9948"
     * 12) "key9965"
     * 13) "key9937"
     * <p>
     * $redis-cli scan 13912 match key99* count 1000
     * 1) "5292"
     * 2)  1) "key996"
     * 2) "key9960"
     * 3) "key9973"
     * 4) "key9978"
     * 5) "key9927"
     * 6) "key995"
     * 7) "key9992"
     * 8) "key9993"
     * 9) "key9964"
     * 10) "key9934"
     * ؽΪ֣һּ 1) һεα꣬ڶּ 2) DZε
     *
     * @param pattern
     * @param count
     * @return
     */
    public static ScanParams buildDefaultScanParams(String pattern, int count) {
        return new ScanParams().match(pattern).count(count);
    }

    /**
     * Ƿ֧scanJedis
     *
     * @param jedis
     * @return
     */
    public static Boolean isSupportScanCommand(Jedis jedis) {
        try {
            ScanParams scanParams = buildDefaultScanParams(SCAN_TEST_PATTERN, SCAN_COUNT);
            jedis.scan(SCAN_INIT_CURSOR, scanParams);
        } catch (JedisDataException e) {
            logger.error(e.getMessage(), e);
            logger.info("Redis **NOT** support scan command");
            return false;
        }

        logger.info("Redis support scan command");
        return true;
    }
}

================================================
FILE: tyloo-core/src/main/java/io/tyloo/repository/helper/TransactionSerializer.java
================================================
package io.tyloo.repository.helper;

import io.tyloo.Transaction;
import io.tyloo.serializer.ObjectSerializer;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/*
 *
 * л
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:08 2019/5/8
 *
 */

public class TransactionSerializer {

    public static byte[] serialize(ObjectSerializer serializer, Transaction transaction) throws CloneNotSupportedException {
        Map<String, Object> map = new HashMap<>();

        map.put("GLOBAL_TX_ID", transaction.getXid().getGlobalTransactionId());
        map.put("BRANCH_QUALIFIER", transaction.getXid().getBranchQualifier());
        map.put("STATUS", transaction.getStatus().getId());
        map.put("TRANSACTION_TYPE", transaction.getTransactionType().getId());
        map.put("RETRIED_COUNT", transaction.getRetriedCount());
        map.put("CREATE_TIME", transaction.getCreateTime());
        map.put("LAST_UPDATE_TIME", transaction.getLastUpdateTime());
        map.put("VERSION", transaction.getVersion());
        map.put("CONTENT", serializer.serialize(transaction));

        return serializer.serialize(map);
    }

    public static Transaction deserialize(ObjectSerializer serializer, byte[] value) {

        Map<String, Object> map = (Map<String, Object>) serializer.deserialize(value);

        byte[] content = (byte[]) map.get("CONTENT");
        Transaction transaction = (Transaction) serializer.deserialize(content);
        transaction.resetRetriedCount((Integer) map.get("RETRIED_COUNT"));
        transaction.setLastUpdateTime((Date) map.get("LAST_UPDATE_TIME"));
        transaction.setVersion((Long) map.get("VERSION"));
        return transaction;
    }
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/serializer/JacksonJsonSerializer.java
================================================
package io.tyloo.serializer;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import io.tyloo.SystemException;
import io.tyloo.Transaction;

import java.io.IOException;

/*
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:29 2019/12/4
 *
 */

public class JacksonJsonSerializer implements ObjectSerializer<Transaction> {

    private static ObjectMapper objectMapper = new ObjectMapper();

    static {
//        objectMapper.enableDefaultTypingAsProperty(ObjectMapper.DefaultTyping.NON_FINAL,"@class");
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);

    }

    @Override
    public byte[] serialize(Transaction transaction) {
        try {
            return objectMapper.writeValueAsBytes(transaction);
        } catch (JsonProcessingException e) {
            throw new SystemException(String.format("serialize object failed. object:%s", transaction), e);
        }
    }

    @Override
    public Transaction deserialize(byte[] bytes) {
        try {
            return objectMapper.readValue(bytes, Transaction.class);
        } catch (IOException e) {
            throw new SystemException(String.format("deserialize object failed."), e);
        }
    }

    @Override
    public Transaction clone(Transaction object) {
        return deserialize(serialize(object));
    }

}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/serializer/JdkSerializationSerializer.java
================================================
package io.tyloo.serializer;

import io.tyloo.Transaction;
import org.apache.commons.lang3.SerializationUtils;

/*
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:29 2019/5/22
 *
 */

public class JdkSerializationSerializer implements ObjectSerializer<Transaction> {

    @Override
    public byte[] serialize(Transaction object) {
        return SerializationUtils.serialize(object);
    }

    @Override
    public Transaction deserialize(byte[] bytes) {
        if (bytes == null) {
            return null;
        } else {
            return (Transaction) SerializationUtils.deserialize(bytes);
        }
    }

    @Override
    public Transaction clone(Transaction object) {
        return SerializationUtils.clone(object);
    }
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/serializer/KryoPoolSerializer.java
================================================
package io.tyloo.serializer;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.pool.KryoCallback;
import com.esotericsoftware.kryo.pool.KryoFactory;
import com.esotericsoftware.kryo.pool.KryoPool;
import io.tyloo.Transaction;
import org.objenesis.strategy.StdInstantiatorStrategy;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

/*
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:29 2019/5/22
 *
 */

public class KryoPoolSerializer implements ObjectSerializer<Transaction> {


    static KryoFactory factory = () -> {
        Kryo kryo = new Kryo();
        kryo.setReferences(true);
        kryo.setRegistrationRequired(false);
        //Fix the NPE bug when deserializing Collections.
        ((Kryo.DefaultInstantiatorStrategy) kryo.getInstantiatorStrategy())
                .setFallbackInstantiatorStrategy(new StdInstantiatorStrategy());

        return kryo;
    };


    KryoPool pool = new KryoPool.Builder(factory).softReferences().build();

    private int initPoolSize = 300;

    public KryoPoolSerializer() {
        init();
    }

    public KryoPoolSerializer(int initPoolSize) {
        this.initPoolSize = initPoolSize;
        init();
    }

    private void init() {

        for (int i = 0; i < initPoolSize; i++) {
            Kryo kryo = pool.borrow();
            pool.release(kryo);
        }
    }

    @Override
    public byte[] serialize(final Transaction object) {

        return pool.run(kryo -> {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            Output output = new Output(byteArrayOutputStream);

            kryo.writeClassAndObject(output, object);
            output.flush();

            return byteArrayOutputStream.toByteArray();
        });
    }

    @Override
    public Transaction deserialize(final byte[] bytes) {

        return pool.run(kryo -> {
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
            Input input = new Input(byteArrayInputStream);

            return (Transaction) kryo.readClassAndObject(input);
        });
    }

    @Override
    public Transaction clone(final Transaction object) {
        return pool.run(kryo -> kryo.copy(object));
    }
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/serializer/ObjectSerializer.java
================================================
package io.tyloo.serializer;

/*
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:29 2019/5/22
 *
 */
public interface ObjectSerializer<T> {

    /**
     * Serialize the given object to binary data.
     *
     * @param t object to serialize
     * @return the equivalent binary data
     */
    byte[] serialize(T t);

    /**
     * Deserialize an object from the given binary data.
     *
     * @param bytes object binary representation
     * @return the equivalent object instance
     */
    T deserialize(byte[] bytes);


    T clone(T object);
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/support/BeanFactory.java
================================================
package io.tyloo.support;

/*
 *
 * Bean
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:34 2019/5/27
 *
 */

public interface BeanFactory {
    <T> T getBean(Class<T> var1);

    <T> boolean isFactoryOf(Class<T> clazz);
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/support/FactoryBuilder.java
================================================
package io.tyloo.support;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/*
 *
 * Bean
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:35 2019/5/27
 *
 */
public final class FactoryBuilder {


    private FactoryBuilder() {

    }

    /**
     * Bean 
     */
    private static List<BeanFactory> beanFactories = new ArrayList<BeanFactory>();

    /**
     * Bean ӳ
     */
    private static ConcurrentHashMap<Class, SingeltonFactory> classFactoryMap = new ConcurrentHashMap<>();

    /**
     * ָ൥
     *
     * @param <T>   
     * @param clazz ָ
     * @return 
     */
    public static <T> SingeltonFactory<T> factoryOf(Class<T> clazz) {

        if (!classFactoryMap.containsKey(clazz)) {
            for (BeanFactory beanFactory : beanFactories) {
                if (beanFactory.isFactoryOf(clazz)) {
                    classFactoryMap.putIfAbsent(clazz, new SingeltonFactory<T>(clazz, beanFactory.getBean(clazz)));
                }
            }
            if (!classFactoryMap.containsKey(clazz)) {
                classFactoryMap.putIfAbsent(clazz, new SingeltonFactory<T>(clazz));
            }
        }

        return classFactoryMap.get(clazz);
    }

    /**
     * BeanעᵽǰBuilder
     *
     * @param beanFactory Bean
     */
    public static void registerBeanFactory(BeanFactory beanFactory) {
        beanFactories.add(beanFactory);
    }

    /**
     * 
     *
     * @param <T> 
     */
    public static class SingeltonFactory<T> {

        private volatile T instance = null;

        private String className;

        public SingeltonFactory(Class<T> clazz, T instance) {
            this.className = clazz.getName();
            this.instance = instance;
        }

        public SingeltonFactory(Class<T> clazz) {
            this.className = clazz.getName();
        }

        /**
         * õ
         *
         * @return 
         */
        public T getInstance() {
            if (instance == null) {
                synchronized (SingeltonFactory.class) {
                    if (instance == null) {
                        try {
                            ClassLoader loader = Thread.currentThread().getContextClassLoader();
                            Class<?> clazz = loader.loadClass(className);
                            instance = (T) clazz.newInstance();
                        } catch (Exception e) {
                            throw new RuntimeException("Failed to create an instance of " + className, e);
                        }
                    }
                }
            }

            return instance;
        }

        @Override
        public boolean equals(Object other) {
            if (this == other) {
                return true;
            }
            if (other == null || getClass() != other.getClass()) {
                return false;
            }

            SingeltonFactory that = (SingeltonFactory) other;

            return className.equals(that.className);
        }

        @Override
        public int hashCode() {
            return className.hashCode();
        }
    }
}

================================================
FILE: tyloo-core/src/main/java/io/tyloo/support/TransactionConfigurator.java
================================================
package io.tyloo.support;

import io.tyloo.TransactionManager;
import io.tyloo.TransactionRepository;
import io.tyloo.recover.TylooRecoverConfiguration;

/*
 *
 * 
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:34 2019/5/28
 *
 */

public interface TransactionConfigurator {

    /**
     * ȡ.
     *
     * @return
     */
    TransactionManager getTransactionManager();

    /**
     * ȡ.
     *
     * @return
     */
    TransactionRepository getTransactionRepository();

    /**
     * ȡָ.
     *
     * @return
     */
    TylooRecoverConfiguration getTylooRecoverConfiguration();
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/utils/ByteUtils.java
================================================
package io.tyloo.utils;

/*
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:49 2019/5/30
 *
 */
public class ByteUtils {

    public static byte[] longToBytes(long num) {
        return String.valueOf(num).getBytes();
    }

    public static long bytesToLong(byte[] bytes) {
        return Long.valueOf(new String(bytes));
    }

    public static byte[] intToBytes(int num) {
        return String.valueOf(num).getBytes();
    }

    public static int bytesToInt(byte[] bytes) {
        return Integer.valueOf(new String(bytes));
    }

}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/utils/CollectionUtils.java
================================================
package io.tyloo.utils;

import java.util.Collection;

/*
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:49 2019/5/30
 *
 */
public final class CollectionUtils {

    private CollectionUtils() {

    }

    public static boolean isEmpty(Collection collection) {
        return (collection == null || collection.isEmpty());
    }
}

================================================
FILE: tyloo-core/src/main/java/io/tyloo/utils/ReflectionUtils.java
================================================
package io.tyloo.utils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.Map;

/*
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 18:07 2019/5/19
 *
 */
public class ReflectionUtils {


    public static void makeAccessible(Method method) {

        if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) && !method.isAccessible()) {
            method.setAccessible(true);
        }
    }

    public static Object changeAnnotationValue(Annotation annotation, String key, Object newValue) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {

        Object handler = Proxy.getInvocationHandler(annotation);
        Field f;
        f = handler.getClass().getDeclaredField("memberValues");
        f.setAccessible(true);
        Map<String, Object> memberValues;
        memberValues = (Map<String, Object>) f.get(handler);
        Object oldValue = memberValues.get(key);
        if (oldValue == null || oldValue.getClass() != newValue.getClass()) {
            throw new IllegalArgumentException();
        }
        memberValues.put(key, newValue);
        return oldValue;
    }

    public static Class getDeclaringType(Class aClass, String methodName, Class<?>[] parameterTypes) {

        Method method = null;
        Class findClass = aClass;
        do {
            Class[] clazzes = findClass.getInterfaces();
            for (Class clazz : clazzes) {
                try {
                    method = clazz.getDeclaredMethod(methodName, parameterTypes);
                } catch (NoSuchMethodException e) {
                    method = null;
                }
                if (method != null) {
                    return clazz;
                }
            }
            findClass = findClass.getSuperclass();
        } while (!findClass.equals(Object.class));
        return aClass;
    }

    public static Object getNullValue(Class type) {

        if (boolean.class.equals(type)) {
            return false;
        } else if (byte.class.equals(type)) {
            return 0;
        } else if (short.class.equals(type)) {
            return 0;
        } else if (int.class.equals(type)) {
            return 0;
        } else if (long.class.equals(type)) {
            return 0;
        } else if (float.class.equals(type)) {
            return 0;
        } else if (double.class.equals(type)) {
            return 0;
        } else if (char.class.equals(type)) {
            return ' ';
        }

        return null;
    }
}

================================================
FILE: tyloo-core/src/main/java/io/tyloo/utils/StringUtils.java
================================================
package io.tyloo.utils;

/*
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:49 2019/5/30
 *
 */
public class StringUtils {

    public static boolean isNotEmpty(String value) {

        if(value == null) {
            return false;
        }

        if(value.equals("")) {
            return false;
        }

        return true;
    }
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/utils/TransactionUtils.java
================================================
package io.tyloo.utils;

import io.tyloo.api.Propagation;
import io.tyloo.interceptor.TylooMethodContext;

/*
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:49 2019/5/30
 *
 */
public class TransactionUtils {

    public static boolean isLegalTransactionContext(boolean isTransactionActive, TylooMethodContext tylooMethodContext) {

        return !tylooMethodContext.getPropagation().equals(Propagation.MANDATORY) ||
                isTransactionActive ||
                tylooMethodContext.getTransactionContext() != null;
    }
}


================================================
FILE: tyloo-core/src/main/java/io/tyloo/utils/TylooMethodUtils.java
================================================
package io.tyloo.utils;

import io.tyloo.api.Propagation;
import io.tyloo.api.TransactionContext;
import io.tyloo.api.Tyloo;
import io.tyloo.common.MethodRole;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;

import java.lang.reflect.Method;

/*
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 19:49 2019/5/30
 *
 */
public class TylooMethodUtils {

    public static Method getTylooMethod(ProceedingJoinPoint pjp) {

        Method method = ((MethodSignature) (pjp.getSignature())).getMethod();
        if (method.getAnnotation(Tyloo.class) == null) {
            try {
                method = pjp.getTarget().getClass().getMethod(method.getName(), method.getParameterTypes());
            } catch (NoSuchMethodException e) {
                return null;
            }
        }
        return method;
    }

    public static MethodRole calculateMethodType(Propagation propagation, boolean isTransactionActive, TransactionContext transactionContext) {

        if ((propagation.equals(Propagation.REQUIRED) && !isTransactionActive && transactionContext == null) ||
                propagation.equals(Propagation.REQUIRES_NEW)) {
            return MethodRole.ROOT;
        } else if ((propagation.equals(Propagation.REQUIRED) || propagation.equals(Propagation.MANDATORY)) && !isTransactionActive && transactionContext != null) {
            return MethodRole.PROVIDER;
        } else {
            return MethodRole.NORMAL;
        }
    }

    public static int getTransactionContextParamPosition(Class<?>[] parameterTypes) {

        int position = -1;
        for (int i = 0; i < parameterTypes.length; i++) {
            if (parameterTypes[i].equals(TransactionContext.class)) {
                position = i;
                break;
            }
        }
        return position;
    }
}


================================================
FILE: tyloo-dubbo/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>tyloo</artifactId>
        <groupId>io.tyloo</groupId>
       <version>1.1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>tyloo-dubbo</artifactId>


    <dependencies>
        <dependency>
            <groupId>io.tyloo</groupId>
            <artifactId>tyloo-api</artifactId>
        </dependency>

        <dependency>
            <groupId>io.tyloo</groupId>
            <artifactId>tyloo-core</artifactId>
        </dependency>



        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-dependencies-zookeeper</artifactId>
            <type>pom</type>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
        </dependency>


        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
        </dependency>
    </dependencies>

</project>

================================================
FILE: tyloo-dubbo/src/main/java/io/tyloo/dubbo/constants/TransactionContextConstants.java
================================================
package io.tyloo.dubbo.constants;

/*
 *
 * ij
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 9:33 2019/7/5
 *
 */


public class TransactionContextConstants {
    public static final String TRANSACTION_CONTEXT = "TRANSACTION_CONTEXT";
}


================================================
FILE: tyloo-dubbo/src/main/java/io/tyloo/dubbo/context/DubboTransactionContextEditor.java
================================================
package io.tyloo.dubbo.context;

import com.alibaba.fastjson.JSON;
import io.tyloo.api.TransactionContext;
import io.tyloo.api.TransactionContextEditor;
import io.tyloo.dubbo.constants.TransactionContextConstants;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.RpcContext;

import java.lang.reflect.Method;

/*
 * Dubbo ı༭
 *
 * ײʹõdubboTransactionContextEditorΪDubboTransactionContextEditor.classʹdubboʽηʽ
 * ͨ Dubbo ʽεķʽ Dubbo Service ӿ TransactionContext Խӿڲһ
 * tyloo ͨ Dubbo Proxy Ļƣʵ `@Tyloo` Զ
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 15:32 2019/7/17
 *
 */

public class DubboTransactionContextEditor implements TransactionContextEditor {
    @Override
    public TransactionContext get(Object target, Method method, Object[] args) {

        String context = RpcContext.getContext().getAttachment(TransactionContextConstants.TRANSACTION_CONTEXT);

        if (StringUtils.isNotEmpty(context)) {
            return JSON.parseObject(context, TransactionContext.class);
        }

        return null;
    }

    @Override
    public void set(TransactionContext transactionContext, Object target, Method method, Object[] args) {

        RpcContext.getContext().setAttachment(TransactionContextConstants.TRANSACTION_CONTEXT, JSON.toJSONString(transactionContext));
    }
}


================================================
FILE: tyloo-dubbo/src/main/java/io/tyloo/dubbo/proxy/javassist/TylooClassGenerator.java
================================================
package io.tyloo.dubbo.proxy.javassist;

import javassist.*;
import javassist.bytecode.AnnotationsAttribute;
import javassist.bytecode.ConstPool;
import javassist.bytecode.annotation.Annotation;
import javassist.bytecode.annotation.ClassMemberValue;
import javassist.bytecode.annotation.EnumMemberValue;
import javassist.bytecode.annotation.StringMemberValue;
import org.apache.dubbo.common.utils.ReflectUtils;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;


/*
 *
 * TCC  Javassist ʵ֡
 *      Javassist һԴķ༭ʹ Java ֽ⡣
 * һ Dubbo ServiceTccProxy ᶯ̬ࣺ
        - Dubbo Service  Proxy
        - Dubbo Service  ProxyFactoryɶӦ Dubbo Service Proxy
 *
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 9:33 2019/8/1
 *
 */

public final class TylooClassGenerator {
    private static final AtomicLong CLASS_NAME_COUNTER = new AtomicLong(0);
    private static final String SIMPLE_NAME_TAG = "<init>";
    private static final Map<ClassLoader, ClassPool> POOL_MAP = new ConcurrentHashMap<ClassLoader, ClassPool>(); //ClassLoader - ClassPool
    private final Set<String> tylooMethods = new HashSet<String>();
    private ClassPool mPool;
    private CtClass mCtc;
    private String mClassName, mSuperClass;
    private Set<String> mInterfaces;
    private List<String> mFields, mConstructors, mMethods;
    private Map<String, Method> mCopyMethods; // <method desc,method instance>
    private Map<String, Constructor<?>> mCopyConstructors; // <constructor desc,constructor instance>
    private boolean mDefaultConstructor = false;

    private TylooClassGenerator() {
    }

    private TylooClassGenerator(ClassPool pool) {
        mPool = pool;
    }

    public static TylooClassGenerator newInstance() {
        return new TylooClassGenerator(getClassPool(Thread.currentThread().getContextClassLoader()));
    }

    public static TylooClassGenerator newInstance(ClassLoader loader) {
        return new TylooClassGenerator(getClassPool(loader));
    }

    public static boolean isDynamicClass(Class<?> cl) {
        return TylooClassGenerator.DC.class.isAssignableFrom(cl);
    }

    public static ClassPool getClassPool(ClassLoader loader) {
        if (loader == null) {
            return ClassPool.getDefault();
        }

        ClassPool pool = POOL_MAP.get(loader);
        if (pool == null) {
            pool = new ClassPool(true);
            pool.appendClassPath(new LoaderClassPath(loader));
            POOL_MAP.put(loader, pool);
        }
        return pool;
    }

    private static String modifier(int mod) {
        if (java.lang.reflect.Modifier.isPublic(mod)) {
            return "public";
        }
        if (java.lang.reflect.Modifier.isProtected(mod)) {
            return "protected";
        }
        if (java.lang.reflect.Modifier.isPrivate(mod)) {
            return "private";
        }
        return "";
    }

    public String getClassName() {
        return mClassName;
    }

    public TylooClassGenerator setClassName(String name) {
        mClassName = name;
        return this;
    }

    public TylooClassGenerator addInterface(String cn) {
        if (mInterfaces == null) {
            mInterfaces = new HashSet<String>();
        }
        mInterfaces.add(cn);
        return this;
    }

    public TylooClassGenerator addInterface(Class<?> cl) {
        return addInterface(cl.getName());
    }

    public TylooClassGenerator setSuperClass(String cn) {
        mSuperClass = cn;
        return this;
    }

    public TylooClassGenerator setSuperClass(Class<?> cl) {
        mSuperClass = cl.getName();
        return this;
    }

    public TylooClassGenerator addField(String code) {
        if (mFields == null) {
            mFields = new ArrayList<String>();
        }
        mFields.add(code);
        return this;
    }

    public TylooClassGenerator addField(String name, int mod, Class<?> type) {
        return addField(name, mod, type, null);
    }

    public TylooClassGenerator addField(String name, int mod, Class<?> type, String def) {
        StringBuilder sb = new StringBuilder();
        sb.append(modifier(mod)).append(' ').append(ReflectUtils.getName(type)).append(' ');
        sb.append(name);
        if (def != null && def.length() > 0) {
            sb.append('=');
            sb.append(def);
        }
        sb.append(';');
        return addField(sb.toString());
    }

    public TylooClassGenerator addMethod(String code) {
        if (mMethods == null) {
            mMethods = new ArrayList<String>();
        }
        mMethods.add(code);
        return this;
    }

    public TylooClassGenerator addMethod(String name, int mod, Class<?> rt, Class<?>[] pts, String body) {
        return addMethod(false, name, mod, rt, pts, null, body);
    }

    public TylooClassGenerator addMethod(boolean isTylooMethod, String name, int mod, Class<?> rt, Class<?>[] pts, Class<?>[] ets, String body) {
        StringBuilder sb = new StringBuilder();

        sb.append(modifier(mod)).append(' ').append(ReflectUtils.getName(rt)).append(' ').append(name);
        sb.append('(');
        for (int i = 0; i < pts.length; i++) {
            if (i > 0) {
                sb.append(',');
            }
            sb.append(ReflectUtils.getName(pts[i]));
            sb.append(" arg").append(i);
        }
        sb.append(')');
        if (ets != null && ets.length > 0) {
            sb.append(" throws ");
            for (int i = 0; i < ets.length; i++) {
                if (i > 0) {
                    sb.append(',');
                }
                sb.append(ReflectUtils.getName(ets[i]));
            }
        }
        sb.append('{').append(body).append('}');

        if (isTylooMethod) {
            tylooMethods.add(sb.toString());
        }

        return addMethod(sb.toString());
    }

    public TylooClassGenerator addMethod(Method m) {
        addMethod(m.getName(), m);
        return this;
    }

    public TylooClassGenerator addMethod(String name, Method m) {
        String desc = name + ReflectUtils.getDescWithoutMethodName(m);
        addMethod(':' + desc);
        if (mCopyMethods == null) {
            mCopyMethods = new ConcurrentHashMap<String, Method>(8);
        }
        mCopyMethods.put(desc, m);
        return this;
    }

    public TylooClassGenerator addConstructor(String code) {
        if (mConstructors == null) {
            mConstructors = new LinkedList<String>();
        }
        mConstructors.add(code);
        return this;
    }

    public TylooClassGenerator addConstructor(int mod, Class<?>[] pts, String body) {
        return addConstructor(mod, pts, null, body);
    }

    public TylooClassGenerator addConstructor(int mod, Class<?>[] pts, Class<?>[] ets, String body) {
        StringBuilder sb = new StringBuilder();
        sb.append(modifier(mod)).append(' ').append(SIMPLE_NAME_TAG);
        sb.append('(');
        for (int i = 0; i < pts.length; i++) {
            if (i > 0) {
                sb.append(',');
            }
            sb.append(ReflectUtils.getName(pts[i]));
            sb.append(" arg").append(i);
        }
        sb.append(')');
        if (ets != null && ets.length > 0) {
            sb.append(" throws ");
            for (int i = 0; i < ets.length; i++) {
                if (i > 0) {
                    sb.append(',');
                }
                sb.append(ReflectUtils.getName(ets[i]));
            }
        }
        sb.append('{').append(body).append('}');
        return addConstructor(sb.toString());
    }

    public TylooClassGenerator addConstructor(Constructor<?> c) {
        String desc = ReflectUtils.getDesc(c);
        addConstructor(":" + desc);
        if (mCopyConstructors == null) {
            mCopyConstructors = new ConcurrentHashMap<String, Constructor<?>>(4);
        }
        mCopyConstructors.put(desc, c);
        return this;
    }

    public TylooClassGenerator addDefaultConstructor() {
        mDefaultConstructor = true;
        return this;
    }

    public ClassPool getClassPool() {
        return mPool;
    }

    public Class<?> toClass() {
        if (mCtc != null) {
            mCtc.detach();
        }
        long id = CLASS_NAME_COUNTER.getAndIncrement();
        try {
            CtClass ctcs = mSuperClass == null ? null : mPool.get(mSuperClass);
            if (mClassName == null) {
                mClassName = (mSuperClass == null || Modifier.isPublic(ctcs.getModifiers())
                        ? TylooClassGenerator.class.getName() : mSuperClass + "$sc") + id;
            }
            mCtc = mPool.makeClass(mClassName);
            if (mSuperClass != null) {
                mCtc.setSuperclass(ctcs);
            }
            mCtc.addInterface(mPool.get(DC.class.getName())); // add dynamic class tag.
            if (mInterfaces != null) {
                for (String cl : mInterfaces) {
                    mCtc.addInterface(mPool.get(cl));
                }
            }
            if (mFields != null) {
                for (String code : mFields) {
                    mCtc.addField(CtField.make(code, mCtc));
                }
            }
            if (mMethods != null) {
                for (String code : mMethods) {
                    if (code.charAt(0) == ':') {
                        mCtc.addMethod(CtNewMethod.copy(getCtMethod(mCopyMethods.get(code.substring(1))), code.substring(1, code.indexOf('(')), mCtc, null));
                    } else {

                        CtMethod ctMethod = CtNewMethod.make(code, mCtc);

                        // עⷽ
                        if (tylooMethods.contains(code)) {

                            ConstPool constpool = mCtc.getClassFile().getConstPool();
                            AnnotationsAttribute attr = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag);
                            Annotation annot = new Annotation("Tyloo", constpool);
                            EnumMemberValue enumMemberValue = new EnumMemberValue(constpool);
                            enumMemberValue.setType("Propagation");
                            enumMemberValue.setValue("SUPPORTS");
                            annot.addMemberValue("propagation", enumMemberValue);
                            annot.addMemberValue("confirmMethod", new StringMemberValue(ctMethod.getName(), constpool));
                            annot.addMemberValue("cancelMethod", new StringMemberValue(ctMethod.getName(), constpool));

                            ClassMemberValue classMemberValue = new ClassMemberValue("DubboTransactionContextEditor", constpool);
                            annot.addMemberValue("transactionContextEditor", classMemberValue);

                            attr.addAnnotation(annot);
                            ctMethod.getMethodInfo().addAttribute(attr);
                        }

                        mCtc.addMethod(ctMethod);
                    }
                }
            }
            if (mDefaultConstructor) {
                mCtc.addConstructor(CtNewConstructor.defaultConstructor(mCtc));
            }
            if (mConstructors != null) {
                for (String code : mConstructors) {
                    if (code.charAt(0) == ':') {
                        mCtc.addConstructor(CtNewConstructor.copy(getCtConstructor(mCopyConstructors.get(code.substring(1))), mCtc, null));
                    } else {
                        String[] sn = mCtc.getSimpleName().split("\\$+"); // inner class name include $.
                        mCtc.addConstructor(CtNewConstructor.make(code.replaceFirst(SIMPLE_NAME_TAG, sn[sn.length - 1]), mCtc));
                    }
                }
            }
            return mCtc.toClass();
        } catch (RuntimeException e) {
            throw e;
        } catch (NotFoundException e) {
            throw new RuntimeException(e.getMessage(), e);
        } catch (CannotCompileException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    public void release() {
        if (mCtc != null) {
            mCtc.detach();
        }
        if (mInterfaces != null) {
            mInterfaces.clear();
        }
        if (mFields != null) {
            mFields.clear();
        }
        if (mMethods != null) {
            mMethods.clear();
        }
        if (mConstructors != null) {
            mConstructors.clear();
        }
        if (mCopyMethods != null) {
            mCopyMethods.clear();
        }
        if (mCopyConstructors != null) {
            mCopyConstructors.clear();
        }
    }

    private CtClass getCtClass(Class<?> c) throws NotFoundException {
        return mPool.get(c.getName());
    }

    private CtMethod getCtMethod(Method m) throws NotFoundException {
        return getCtClass(m.getDeclaringClass()).getMethod(m.getName(), ReflectUtils.getDescWithoutMethodName(m));
    }

    private CtConstructor getCtConstructor(Constructor<?> c) throws NotFoundException {
        return getCtClass(c.getDeclaringClass()).getConstructor(ReflectUtils.getDesc(c));
    }

    public interface DC {
    } // dynamic class tag interface.
}

================================================
FILE: tyloo-dubbo/src/main/java/io/tyloo/dubbo/proxy/javassist/TylooJavassistProxyFactory.java
================================================
package io.tyloo.dubbo.proxy.javassist;

import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.proxy.InvokerInvocationHandler;
import org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory;

/*
 *
 *
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 9:33 2019/8/16
 *
 */
public class TylooJavassistProxyFactory extends JavassistProxyFactory {

    /**
     * ĿʱgetProxy(...)`  Dubbo Service  Proxy
     * com.alibaba.dubbo.rpc.proxy.InvokerInvocationHandler`Dubbo ô
     *
     * @param invoker
     * @param interfaces
     * @param <T>
     * @return
     */
    @Override
    @SuppressWarnings("unchecked")
    public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {
        return (T) TylooProxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));
    }
}


================================================
FILE: tyloo-dubbo/src/main/java/io/tyloo/dubbo/proxy/javassist/TylooProxy.java
================================================
/*
 * Copyright 1999-2011 Alibaba Group.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.tyloo.dubbo.proxy.javassist;

import io.tyloo.api.Tyloo;
import org.apache.dubbo.common.utils.ClassHelper;
import org.apache.dubbo.common.utils.ReflectUtils;

import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;

/*
 *
 * TCC Proxy  Dubbo Service  Proxy
 *
 * ο Dubbo Դʵ֣
 *     com.alibaba.dubbo.Enums.bytecode.Proxy
 *     com.alibaba.dubbo.Enums.bytecode.ClassGenerator
 *     com.alibaba.dubbo.Enums.bytecode.Wrapper
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 9:34 2019/8/27
 *
 */
public abstract class TylooProxy {
    public static final InvocationHandler RETURN_NULL_INVOKER = new InvocationHandler() {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) {
            return null;
        }
    };
    public static final InvocationHandler THROW_UNSUPPORTED_INVOKER = (proxy, method, args) -> {
        throw new UnsupportedOperationException("Method [" + ReflectUtils.getName(method) + "] unimplemented.");
    };
    private static final AtomicLong PROXY_CLASS_COUNTER = new AtomicLong(0);
    private static final String PACKAGE_NAME = TylooProxy.class.getPackage().getName();
    private static final Map<ClassLoader, Map<String, Object>> ProxyCacheMap = new WeakHashMap<ClassLoader, Map<String, Object>>();

    private static final Object PendingGenerationMarker = new Object();

    protected TylooProxy() {
    }

    /**
     * TCC Proxy 
     *
     * @param ics interface class array.
     * @return TccProxy instance.
     */
    public static TylooProxy getProxy(Class<?>... ics) {
        return getProxy(ClassHelper.getCallerClassLoader(TylooProxy.class), ics);
    }

    /**
     * 1. Уӿ
     * 2. ʹýӿڼ `;` ָƴӣΪ Proxy Ψһʶ
     * 3.  Proxy Ӧ ClassLoader
     * 4. һֱ Tyloo Proxy ֱɹ
     * 5.  Dubbo Service  ProxyFactoryProxy Ĵ
     * 6.  Dubbo Service  Proxy Ĵ롣
     *
     * @param cl
     * @param ics
     * @return
     */
    public static TylooProxy getProxy(ClassLoader cl, Class<?>... ics) {
        if (ics.length > 65535) {
            throw new IllegalArgumentException("interface limit exceeded");
        }

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < ics.length; i++) {
            String itf = ics[i].getName();
            if (!ics[i].isInterface()) {
                throw new RuntimeException(itf + " is not a interface.");
            }

            Class<?> tmp = null;
            try {
                tmp = Class.forName(itf, false, cl);
            } catch (ClassNotFoundException e) {
            }

            if (tmp != ics[i]) {
                throw new IllegalArgumentException(ics[i] + " is not visible from class loader");
            }

            sb.append(itf).append(';');
        }

        // use interface class name list as key.
        String key = sb.toString();

        // get cache by class loader.
        Map<String, Object> cache;
        synchronized (ProxyCacheMap) {
            cache = ProxyCacheMap.get(cl);
            if (cache == null) {
                cache = new HashMap<String, Object>();
                ProxyCacheMap.put(cl, cache);
            }
        }

        TylooProxy proxy = null;
        synchronized (cache) {
            do {
                Object value = cache.get(key);
                if (value instanceof Reference<?>) {
                    proxy = (TylooProxy) ((Reference<?>) value).get();
                    if (proxy != null) {
                        return proxy;
                    }
                }

                if (value == PendingGenerationMarker) {
                    try {
                        cache.wait();
                    } catch (InterruptedException e) {
                    }
                } else {
                    cache.put(key, PendingGenerationMarker);
                    break;
                }
            }
            while (true);
        }

        /**
         *  Dubbo Service  Proxy Ĵ
         */
        long id = PROXY_CLASS_COUNTER.getAndIncrement();
        String pkg = null;
        TylooClassGenerator ccp = null, ccm = null;
        try {
            ccp = TylooClassGenerator.newInstance(cl);

            Set<String> worked = new HashSet<String>();
            List<Method> methods = new ArrayList<Method>();

            for (int i = 0; i < ics.length; i++) {
                if (!Modifier.isPublic(ics[i].getModifiers())) {
                    String npkg = ics[i].getPackage().getName();
                    if (pkg == null) {
                        pkg = npkg;
                    } else {
                        if (pkg.equals(npkg)) {
                        } else {
                            throw new IllegalArgumentException("non-public interfaces from different packages");
                        }
                    }
                }
                ccp.addInterface(ics[i]);

                for (Method method : ics[i].getMethods()) {
                    String desc = ReflectUtils.getDesc(method);
                    if (worked.contains(desc)) {
                        continue;
                    }
                    worked.add(desc);

                    int ix = methods.size();
                    Class<?> rt = method.getReturnType();
                    Class<?>[] pts = method.getParameterTypes();

                    StringBuilder code = new StringBuilder("Object[] args = new Object[").append(pts.length).append("];");
                    for (int j = 0; j < pts.length; j++) {
                        code.append(" args[").append(j).append("] = ($w)$").append(j + 1).append(";");
                    }
                    code.append(" Object ret = handler.invoke(this, methods[" + ix + "], args);");
                    if (!Void.TYPE.equals(rt)) {
                        code.append(" return ").append(asArgument(rt, "ret")).append(";");
                    }

                    methods.add(method);

                    StringBuilder tylooDesc = new StringBuilder();

                    Tyloo tyloo = method.getAnnotation(Tyloo.class);

                    ccp.addMethod(tyloo != null, method.getName(), method.getModifiers(), rt, pts, method.getExceptionTypes(), code.toString());
                }
            }

            if (pkg == null) {
                pkg = PACKAGE_NAME;
            }

            // create ProxyInstance class.
            String pcn = pkg + ".proxy" + id;
            ccp.setClassName(pcn);
            ccp.addField("public static java.lang.reflect.Method[] methods;");
            ccp.addField("private " + InvocationHandler.class.getName() + " handler;");
            ccp.addConstructor(Modifier.PUBLIC, new Class<?>[]{InvocationHandler.class}, new Class<?>[0], "handler=$1;");
            ccp.addDefaultConstructor();
            Class<?> clazz = ccp.toClass();
            clazz.getField("methods").set(null, methods.toArray(new Method[0]));

            // create TccProxy class.
            String fcn = TylooProxy.class.getName() + id;
            ccm = TylooClassGenerator.newInstance(cl);
            ccm.setClassName(fcn);
            ccm.addDefaultConstructor();
            ccm.setSuperClass(TylooProxy.class);
            ccm.addMethod("public Object newInstance(" + InvocationHandler.class.getName() + " h){ return new " + pcn + "($1); }");
            Class<?> pc = ccm.toClass();
            proxy = (TylooProxy) pc.newInstance();
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        } finally {
            // release TccClassGenerator
            if (ccp != null) {
                ccp.release();
            }
            if (ccm != null) {
                ccm.release();
            }
            synchronized (cache) {
                if (proxy == null) {
                    cache.remove(key);
                } else {
                    cache.put(key, new WeakReference<TylooProxy>(proxy));
                }
                cache.notifyAll();
            }
        }
        return proxy;
    }

    private static String asArgument(Class<?> cl, String name) {
        if (cl.isPrimitive()) {
            if (Boolean.TYPE == cl) {
                return name + "==null?false:((Boolean)" + name + ").booleanValue()";
            }
            if (Byte.TYPE == cl) {
                return name + "==null?(byte)0:((Byte)" + name + ").byteValue()";
            }
            if (Character.TYPE == cl) {
                return name + "==null?(char)0:((Character)" + name + ").charValue()";
            }
            if (Double.TYPE == cl) {
                return name + "==null?(double)0:((Double)" + name + ").doubleValue()";
            }
            if (Float.TYPE == cl) {
                return name + "==null?(float)0:((Float)" + name + ").floatValue()";
            }
            if (Integer.TYPE == cl) {
                return name + "==null?(int)0:((Integer)" + name + ").intValue()";
            }
            if (Long.TYPE == cl) {
                return name + "==null?(long)0:((Long)" + name + ").longValue()";
            }
            if (Short.TYPE == cl) {
                return name + "==null?(short)0:((Short)" + name + ").shortValue()";
            }
            throw new RuntimeException(name + " is unknown primitive type.");
        }
        return "(" + ReflectUtils.getName(cl) + ")" + name;
    }

    /**
     * get instance with default handler.
     *
     * @return instance.
     */
    public Object newInstance() {
        return newInstance(THROW_UNSUPPORTED_INVOKER);
    }

    /**
     * get instance with special handler.
     *
     * @return instance.
     */
    abstract public Object newInstance(InvocationHandler handler);
}

================================================
FILE: tyloo-dubbo/src/main/java/io/tyloo/dubbo/proxy/jdk/MethodProceedingJoinPoint.java
================================================
package io.tyloo.dubbo.proxy.jdk;

import io.tyloo.SystemException;
import io.tyloo.utils.ReflectionUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;
import org.aspectj.lang.reflect.SourceLocation;
import org.aspectj.runtime.internal.AroundClosure;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;


/*
 *
 * ɷ
 *
 * ο [`org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint`](https://github.com/spring-projects/spring-framework/blob/master/spring-aop/src/main/java/org/springframework/aop/aspectj/MethodInvocationProceedingJoinPoint.java) ʵ֡
 * 洦ɺ󣬵 `#proceed(...)` Զ Dubbo Service á
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 10:56 2019/9/12
 *
 */

public class MethodProceedingJoinPoint implements ProceedingJoinPoint, JoinPoint.StaticPart {

    private final Object proxy;

    private final Object target;

    private final Method method;

    private final Object[] args;

    private Signature signature;

    /**
     * Lazily initialized source location object
     */
    private SourceLocation sourceLocation;

    /**
     * @param proxy  
     * @param target Ŀ
     * @param method 
     * @param args   
     */
    public MethodProceedingJoinPoint(Object proxy, Object target, Method method, Object[] args) {
        this.proxy = proxy;
        this.target = target;
        this.method = method;
        this.args = args;
    }

    /**
     * Զ Dubbo Service 
     *
     * @return
     * @throws Throwable
     */
    @Override
    public void set$AroundClosure(AroundClosure aroundClosure) {
        throw new UnsupportedOperationException();
    }

    @Override
    public Object proceed() throws Throwable {

        // Use reflection to invoke the method.
        try {
            ReflectionUtils.makeAccessible(method);
            return method.invoke(target, args);
        } catch (InvocationTargetException ex) {
            // Invoked method threw a checked exception.
            // We must rethrow it. The client won't see the interceptor.
            throw ex.getTargetException();
        } catch (IllegalArgumentException ex) {
            throw new SystemException("Tried calling method [" +
                    method + "] on target [" + target + "] failed", ex);
        } catch (IllegalAccessException ex) {
            throw new SystemException("Could not access method [" + method + "]", ex);
        }
    }

    @Override
    public Object proceed(Object[] objects) throws Throwable {

        // Use reflection to invoke the method.
        try {
            ReflectionUtils.makeAccessible(method);
            return method.invoke(target, objects);
        } catch (InvocationTargetException ex) {
            throw ex.getTargetException();
        } catch (IllegalArgumentException ex) {
            throw new SystemException("Tried calling method [" +
                    method + "] on target [" + target + "] failed", ex);
        } catch (IllegalAccessException ex) {
            throw new SystemException("Could not access method [" + method + "]", ex);
        }
    }

    @Override
    public String toShortString() {
        return "execution(" + getSignature().toShortString() + ")";
    }

    @Override
    public String toLongString() {
        return "execution(" + getSignature().toLongString() + ")";
    }

    @Override
    public String toString() {
        return "execution(" + getSignature().toString() + ")";
    }

    @Override
    public Object getThis() {
        return this.proxy;
    }

    @Override
    public Object getTarget() {
        return this.target;
    }

    @Override
    public Object[] getArgs() {
        return this.args;
    }

    @Override
    public Signature getSignature() {
        if (this.signature == null) {
            this.signature = new MethodSignatureImpl();
        }
        return signature;
    }

    @Override
    public SourceLocation getSourceLocation() {
        if (this.sourceLocation == null) {
            this.sourceLocation = new SourceLocationImpl();
        }
        return this.sourceLocation;
    }

    @Override
    public String getKind() {
        return ProceedingJoinPoint.METHOD_EXECUTION;
    }

    @Override
    public int getId() {
        return 0;
    }

    @Override
    public StaticPart getStaticPart() {
        return this;
    }

    /**
     * Lazily initialized MethodSignature.
     */
    private class MethodSignatureImpl implements MethodSignature {

        private volatile String[] parameterNames;

        @Override
        public String getName() {
            return method.getName();
        }

        @Override
        public int getModifiers() {
            return method.getModifiers();
        }

        @Override
        public Class getDeclaringType() {
            return method.getDeclaringClass();
        }

        @Override
        public String getDeclaringTypeName() {
            return method.getDeclaringClass().getName();
        }

        @Override
        public Class getReturnType() {
            return method.getReturnType();
        }

        @Override
        public Method getMethod() {
            return method;
        }

        @Override
        public Class[] getParameterTypes() {
            return method.getParameterTypes();
        }

        @Override
        public String[] getParameterNames() {
            throw new UnsupportedOperationException();
        }

        @Override
        public Class[] getExceptionTypes() {
            return method.getExceptionTypes();
        }

        @Override
        public String toShortString() {
            return toString(false, false, false, false);
        }

        @Override
        public String toLongString() {
            return toString(true, true, true, true);
        }

        @Override
        public String toString() {
            return toString(false, true, false, true);
        }

        private String toString(boolean includeModifier, boolean includeReturnTypeAndArgs,
                                boolean useLongReturnAndArgumentTypeName, boolean useLongTypeName) {
            StringBuilder sb = new StringBuilder();
            if (includeModifier) {
                sb.append(Modifier.toString(getModifiers()));
                sb.append(" ");
            }
            if (includeReturnTypeAndArgs) {
                appendType(sb, getReturnType(), useLongReturnAndArgumentTypeName);
                sb.append(" ");
            }
            appendType(sb, getDeclaringType(), useLongTypeName);
            sb.append(".");
            sb.append(getMethod().getName());
            sb.append("(");
            Class[] parametersTypes = getParameterTypes();
            appendTypes(sb, parametersTypes, includeReturnTypeAndArgs, useLongReturnAndArgumentTypeName);
            sb.append(")");
            return sb.toString();
        }

        private void appendTypes(StringBuilder sb, Class<?>[] types,
                                 boolean includeArgs, boolean useLongReturnAndArgumentTypeName) {
            if (includeArgs) {
                for (int size = types.length, i = 0; i < size; i++) {
                    appendType(sb, types[i], useLongReturnAndArgumentTypeName);
                    if (i < size - 1) {
                        sb.append(",");
                    }
                }
            } else {
                if (types.length != 0) {
                    sb.append("..");
                }
            }
        }

        private void appendType(StringBuilder sb, Class<?> type, boolean useLongTypeName) {
            if (type.isArray()) {
                appendType(sb, type.getComponentType(), useLongTypeName);
                sb.append("[]");
            } else {
                sb.append(useLongTypeName ? type.getName() : type.getSimpleName());
            }
        }
    }


    /**
     * Lazily initialized SourceLocation.
     */
    private class SourceLocationImpl implements SourceLocation {

        @Override
        public Class getWithinType() {
            if (proxy == null) {
                throw new UnsupportedOperationException("No source location joinpoint available: target is null");
            }
            return proxy.getClass();
        }

        @Override
        public String getFileName() {
            throw new UnsupportedOperationException();
        }

        @Override
        public int getLine() {
            throw new UnsupportedOperationException();
        }

        @Override
        public int getColumn() {
            throw new UnsupportedOperationException();
        }
    }

}


================================================
FILE: tyloo-dubbo/src/main/java/io/tyloo/dubbo/proxy/jdk/TylooInvokerInvocationHandler.java
================================================
package io.tyloo.dubbo.proxy.jdk;

import io.tyloo.api.Propagation;
import io.tyloo.api.Tyloo;
import io.tyloo.dubbo.context.DubboTransactionContextEditor;
import io.tyloo.interceptor.TylooCoordinatorAspect;
import io.tyloo.support.FactoryBuilder;
import io.tyloo.utils.ReflectionUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.proxy.InvokerInvocationHandler;
import org.aspectj.lang.ProceedingJoinPoint;

import java.lang.reflect.Method;

/*
 *
 * TCC ô
 * ڵ Dubbo Service ʱʹ TylooCoordinatorAspect ش
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 10:55 2019/9/23
 *
 */

public class TylooInvokerInvocationHandler extends InvokerInvocationHandler {

    private Object target;

    public TylooInvokerInvocationHandler(Invoker<?> handler) {
        super(handler);
    }

    public <T> TylooInvokerInvocationHandler(T target, Invoker<T> invoker) {
        super(invoker);
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        Tyloo tyloo = method.getAnnotation(Tyloo.class);

        if (tyloo != null) {

            if (StringUtils.isEmpty(tyloo.confirmMethod())) {
                ReflectionUtils.changeAnnotationValue(tyloo, "confirmMethod", method.getName());
                ReflectionUtils.changeAnnotationValue(tyloo, "cancelMethod", method.getName());
                ReflectionUtils.changeAnnotationValue(tyloo, "transactionContextEditor", DubboTransactionContextEditor.class);
                ReflectionUtils.changeAnnotationValue(tyloo, "propagation", Propagation.SUPPORTS);
            }

            /**
             * ɷ
             *  TylooCoordinatorAspect#interceptTransactionContextMethod Էش
             * Ϊʲô TylooTransactionAspect 棿
             * ΪΪ Propagation.SUPPORTSᷢ
             */
            ProceedingJoinPoint pjp = new MethodProceedingJoinPoint(proxy, target, method, args);
            return FactoryBuilder.factoryOf(TylooCoordinatorAspect.class).getInstance().interceptTransactionContextMethod(pjp);
        } else {
            return super.invoke(target, method, args);
        }
    }


}


================================================
FILE: tyloo-dubbo/src/main/java/io/tyloo/dubbo/proxy/jdk/TylooJdkProxyFactory.java
================================================
package io.tyloo.dubbo.proxy.jdk;

import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.proxy.InvokerInvocationHandler;
import org.apache.dubbo.rpc.proxy.jdk.JdkProxyFactory;

import java.lang.reflect.Proxy;


/*
 *
 * TCC JDK 
 *  JDK ̬
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 10:52 2019/9/29
 *
 */
public class TylooJdkProxyFactory extends JdkProxyFactory {
    /**
     * - Ŀʱ `TccJavassistProxyFactory#getProxy(...)`  Dubbo Service  Proxy
     * - һε `Proxy#newProxyInstance(...)`  Dubbo Service  Proxy
     * - ڶε `Proxy#newProxyInstance(...)` Ե Dubbo Service  Proxy  Proxy
     *
     * @param invoker
     * @param interfaces
     * @param <T>
     * @return
     */
    @Override
    @SuppressWarnings("unchecked")
    public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {

        T proxy = (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), interfaces, new InvokerInvocationHandler(invoker));

        T tccProxy = (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), interfaces, new TylooInvokerInvocationHandler(proxy, invoker));

        return tccProxy;
    }
}

================================================
FILE: tyloo-dubbo/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.ProxyFactory
================================================
tylooJavassist=TylooJavassistProxyFactory
tylooJdk=TylooJdkProxyFactory

================================================
FILE: tyloo-dubbo/src/main/resources/tyloo-dubbo.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"
       xmlns:aop="http://www.springframework.org/schema/aop">

       <dubbo:provider proxy="tylooJavassist"/>
    <aop:aspectj-autoproxy/>
</beans>

================================================
FILE: tyloo-spring/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>tyloo</artifactId>
        <groupId>io.tyloo</groupId>
       <version>1.1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>tyloo-spring</artifactId>

    <dependencies>

        <dependency>
            <groupId>io.tyloo</groupId>
            <artifactId>tyloo-core</artifactId>
        </dependency>

        <dependency>
            <groupId>io.tyloo</groupId>
            <artifactId>tyloo-api</artifactId>
        </dependency>




        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>

        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>


    </dependencies>

</project>

================================================
FILE: tyloo-spring/src/main/dbscripts/db.sql
================================================
CREATE TABLE `TCC_TRANSACTION` (
  `TRANSACTION_ID` int(11) NOT NULL AUTO_INCREMENT,
  `DOMAIN` varchar(100) DEFAULT NULL,
  `GLOBAL_TX_ID` varbinary(32) NOT NULL,
  `BRANCH_QUALIFIER` varbinary(32) NOT NULL,
  `CONTENT` varbinary(8000) DEFAULT NULL,
  `STATUS` int(11) DEFAULT NULL,
  `TRANSACTION_TYPE` int(11) DEFAULT NULL,
  `RETRIED_COUNT` int(11) DEFAULT NULL,
  `CREATE_TIME` datetime DEFAULT NULL,
  `LAST_UPDATE_TIME` datetime DEFAULT NULL,
  `VERSION` int(11) DEFAULT NULL,
  PRIMARY KEY (`TRANSACTION_ID`),
  UNIQUE KEY `UX_TX_BQ` (`GLOBAL_TX_ID`,`BRANCH_QUALIFIER`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

ALTER TABLE `TCC_TRANSACTION` ADD `IS_DELETE` tinyint(1) DEFAULT 0 NOT NULL;


================================================
FILE: tyloo-spring/src/main/java/io/tyloo/spring/ConfigurableCoordinatorAspect.java
================================================
package io.tyloo.spring;

import io.tyloo.interceptor.TylooCoordinatorAspect;
import io.tyloo.interceptor.TylooCoordinatorInterceptor;
import io.tyloo.support.TransactionConfigurator;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.Ordered;

/*
 *
 * õԴЭ
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 20:21 2019/10/4
 *
 */

@Aspect
public class ConfigurableCoordinatorAspect extends TylooCoordinatorAspect implements Ordered {

    private TransactionConfigurator transactionConfigurator;

    /**
     * ʼ
     * ע TylooTransactionManager
     */
    public void init() {

        TylooCoordinatorInterceptor tylooCoordinatorInterceptor = new TylooCoordinatorInterceptor();
        tylooCoordinatorInterceptor.setTransactionManager(transactionConfigurator.getTransactionManager());
        this.setTylooCoordinatorInterceptor(tylooCoordinatorInterceptor);
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE + 1;
    }

    public void setTransactionConfigurator(TransactionConfigurator transactionConfigurator) {
        this.transactionConfigurator = transactionConfigurator;
    }
}


================================================
FILE: tyloo-spring/src/main/java/io/tyloo/spring/ConfigurableTransactionAspect.java
================================================
package io.tyloo.spring;

import io.tyloo.TransactionManager;
import io.tyloo.interceptor.TylooTransactionAspect;
import io.tyloo.interceptor.TylooTransactionInterceptor;
import io.tyloo.support.TransactionConfigurator;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.Ordered;

/*
 *
 * õĿɲ
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 20:13 2019/10/7
 *
 */
@Aspect
public class ConfigurableTransactionAspect extends TylooTransactionAspect implements Ordered {

    private TransactionConfigurator transactionConfigurator;

    /**
     * ʼ
     * ע DelayCancelExceptions  setTylooTransactionManager
     */
    public void init() {

        TransactionManager transactionManager = transactionConfigurator.getTransactionManager();

        TylooTransactionInterceptor tylooTransactionInterceptor = new TylooTransactionInterceptor();
        tylooTransactionInterceptor.setTransactionManager(transactionManager);
        tylooTransactionInterceptor.setDelayCancelExceptions(transactionConfigurator.getTylooRecoverConfiguration().getDelayCancelExceptions());

        this.setTylooTransactionInterceptor(tylooTransactionInterceptor);
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }

    public void setTransactionConfigurator(TransactionConfigurator transactionConfigurator) {
        this.transactionConfigurator = transactionConfigurator;
    }
}


================================================
FILE: tyloo-spring/src/main/java/io/tyloo/spring/recover/DefaultTylooRecoverConfiguration.java
================================================
package io.tyloo.spring.recover;

import io.tyloo.OptimisticLockException;
import io.tyloo.recover.TylooRecoverConfiguration;
import lombok.*;

import java.net.SocketTimeoutException;
import java.util.HashSet;
import java.util.Set;

/*
 *
 * Ĭָ
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 20:14 2019/10/10
 *
 */

@AllArgsConstructor
@Data
@Builder
public class DefaultTylooRecoverConfiguration implements TylooRecoverConfiguration {

    public static final TylooRecoverConfiguration INSTANCE = new DefaultTylooRecoverConfiguration();

    /**
     * һೢԻָԶָҪ˹ԤĬ30Σ
     */
    private int maxRetryCount = 30;

    /**
     * һ־һʱûи¾ͻᱻΪǷ쳣Ҫָ
     * ָJobɨ賬ʱûиµ־Щлָʱ䵥λ룬Ĭ120
     */
    private int recoverDuration = 120; //120 seconds

    /**
     * ָJobãĬ(ÿ)
     * cron ʽ
     * 0/30 * * * * ?ÿ 30 ִһΡ
     */
    private String cronExpression = "0 */1 * * * ?";

    private int asyncTerminateThreadCorePoolSize = 512;

    private int asyncTerminateThreadMaxPoolSize = 1024;

    private int asyncTerminateThreadWorkQueueSize = 512;

    /**
     * ӳȡ쳣
     */
    private Set<Class<? extends Exception>> delayCancelExceptions = new HashSet<Class<? extends Exception>>();

    public DefaultTylooRecoverConfiguration() {

        /**
         *  SocketTimeoutException ָʱС Socket ʱʱ䣬ʱָԶ̲ȡع
         * Զ̲´θʱΪֹʧܣ׳ OptimisticLockException TylooInterceptor ʱȡع
         * ܻͶʱȡعͻͳһʱ
         *
         */
        delayCancelExceptions.add(OptimisticLockException.class);
        /**
         * try ׶ΣزߵԶ̲( Զ̷ DubboHttp )Զ̲ try ׶εķ߼ִʱϳ Socket ȴʱ SocketTimeoutException
         * ִعԶ̲ try ķδִɣܵ cancel ķʵδִ( try ķδִɣݿ񡾷 TCC δύ
         * cancel ķȡʱδ·ʵδִУ try ķִύݿ񡾷 TCC 񡿣Ϊ )ݲһ¡
         * ָʱȡعʱԶ̲ߵ try ķδǿܷݲһ¡
         *
         */
        delayCancelExceptions.add(SocketTimeoutException.class);
    }


    @Override
    public void setDelayCancelExceptions(Set<Class<? extends Exception>> delayCancelExceptions) {
        this.delayCancelExceptions.addAll(delayCancelExceptions);
    }

}


================================================
FILE: tyloo-spring/src/main/java/io/tyloo/spring/recover/RecoverScheduledJob.java
================================================
package io.tyloo.spring.recover;

import io.tyloo.SystemException;
import io.tyloo.recover.TylooTransactionRecovery;
import io.tyloo.support.TransactionConfigurator;
import org.quartz.Scheduler;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;

/*
 *
 * ָʱ
 *  Quartz ʵֵȣִָ
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 20:15 2019/10/29
 *
 */

public class RecoverScheduledJob {

    /**
     * ָ
     */
    private TylooTransactionRecovery tylooTransactionRecovery;

    /**
     * עTCC.
     */
    private TransactionConfigurator transactionConfigurator;

    /**
     * ָ(עorg.springframework.scheduling.quartz.SchedulerFactoryBeanʵ)
     */
    private Scheduler scheduler;

    /**
     * ʼSpringʱִ.
     */
    public void init() {

        try {
            // MethodInvokingJobDetailFactoryBean ɾֻҪָijijڴʱָָ
            MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();

            // ָӦĵöʵκνӿ
            jobDetail.setTargetObject(tylooTransactionRecovery);

            // ָtargetObjectijķ(˴TransactionRecoveryеstartRecover)
            jobDetail.setTargetMethod("startRecover");

            // 
            jobDetail.setName("transactionRecoveryJob");

            // Ƿ񲢷ִУĬDzִеģʱáconcurrentΪfalseܴܿ⣬ҼʽС׸,
            // Ϊfalseʾһִٿµ
            jobDetail.setConcurrent(false);
            jobDetail.afterPropertiesSet();

            // ࣬ñָĵָĴ
            // ฺspringдһIDӦSchedulerFactoryBeanԵListбãܱ֤ijָ
            CronTriggerFactoryBean cronTrigger = new CronTriggerFactoryBean();

            // ô
            cronTrigger.setBeanName("transactionRecoveryCronTrigger");
            // ͨȡָʱ
            cronTrigger.setCronExpression(transactionConfigurator.getTylooRecoverConfiguration().getCronExpression());
            cronTrigger.setJobDetail(jobDetail.getObject());
            cronTrigger.afterPropertiesSet();

            // õ
            scheduler.scheduleJob(jobDetail.getObject(), cronTrigger.getObject());

            // 
            scheduler.start();

        } catch (Exception e) {
            throw new SystemException(e);
        }
    }

    public void setTylooTransactionRecovery(TylooTransactionRecovery tylooTransactionRecovery) {
        this.tylooTransactionRecovery = tylooTransactionRecovery;
    }

    public Scheduler getScheduler() {
        return scheduler;
    }

    public void setScheduler(Scheduler scheduler) {
        this.scheduler = scheduler;
    }

    public void setTransactionConfigurator(TransactionConfigurator transactionConfigurator) {
        this.transactionConfigurator = transactionConfigurator;
    }
}


================================================
FILE: tyloo-spring/src/main/java/io/tyloo/spring/repository/SpringJdbcTransactionRepository.java
================================================
package io.tyloo.spring.repository;


import io.tyloo.repository.JdbcTransactionRepository;
import org.springframework.jdbc.datasource.DataSourceUtils;

import java.sql.Connection;

/*
 *
 * SpringJdbc
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 20:18 2019/10/30
 *
 */

public class SpringJdbcTransactionRepository extends JdbcTransactionRepository {

    @Override
    protected Connection getConnection() {
        return DataSourceUtils.getConnection(this.getDataSource());
    }

    @Override
    protected void releaseConnection(Connection con) {
        DataSourceUtils.releaseConnection(con, this.getDataSource());
    }
}


================================================
FILE: tyloo-spring/src/main/java/io/tyloo/spring/support/SpringBeanFactory.java
================================================
package io.tyloo.spring.support;

import io.tyloo.support.BeanFactory;
import io.tyloo.support.FactoryBuilder;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.util.Map;

/*
 *
 * Spring Bean 
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 20:12 2019/11/11
 *
 */

public class SpringBeanFactory implements BeanFactory, ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
        FactoryBuilder.registerBeanFactory(this);
    }

    @Override
    public boolean isFactoryOf(Class clazz) {
        Map map = this.applicationContext.getBeansOfType(clazz);
        return map.size() > 0;
    }

    @Override
    public <T> T getBean(Class<T> var1) {
        return this.applicationContext.getBean(var1);
    }
}


================================================
FILE: tyloo-spring/src/main/java/io/tyloo/spring/support/SpringPostProcessor.java
================================================
package io.tyloo.spring.support;

import io.tyloo.support.BeanFactory;
import io.tyloo.support.FactoryBuilder;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;

/*
 *
 * Spring ô
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 20:13 2019/11/18
 *
 */

public class SpringPostProcessor implements ApplicationListener<ContextRefreshedEvent> {
    /**
     * Springʱ.
     */
    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        ApplicationContext applicationContext = contextRefreshedEvent.getApplicationContext();

        if (applicationContext.getParent() == null) {
            FactoryBuilder.registerBeanFactory(applicationContext.getBean(BeanFactory.class));
        }
    }
}


================================================
FILE: tyloo-spring/src/main/java/io/tyloo/spring/support/SpringTransactionConfigurator.java
================================================
package io.tyloo.spring.support;

import io.tyloo.TransactionManager;
import io.tyloo.TransactionRepository;
import io.tyloo.recover.TylooRecoverConfiguration;
import io.tyloo.repository.CachableTransactionRepository;
import io.tyloo.spring.recover.DefaultTylooRecoverConfiguration;
import io.tyloo.support.TransactionConfigurator;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/*
 *
 * Spring
 *
 * @Author:Zh1Cheung zh1cheunglq@gmail.com
 * @Date: 20:20 2019/12/4
 *
 */
public class SpringTransactionConfigurator implements TransactionConfigurator {

    private static volatile ExecutorService executorService = null;

    @Autowired
    private TransactionRepository transactionRepository;

    @Autowired(required = false)
    private TylooRecoverConfiguration tylooRecoverConfiguration = DefaultTylooRecoverConfiguration.INSTANCE;


    private TransactionManager transactionManager;

    public void init() {
        transactionManager = new TransactionManager();
        transactionManager.setTransactionRepository(transactionRepository);

        if (executorService == null) {
            Executors.defaultThreadFactory();
            synchronized (SpringTransactionConfigurator.class) {
                if (executorService == null) {
                    executorService = new ThreadPoolExecutor(
                            tylooRecoverConfiguration.getAsyncTerminateThreadCorePoolSize(),
                            tylooRecoverConfiguration.getAsyncTerminateThreadMaxPoolSize(),
                            5L,
                            TimeUnit.SECONDS,
                            new ArrayBlockingQueue<>(tylooRecoverConfiguration.getAsyncTerminateThreadWorkQueueSize()),
                            new ThreadFactory() {

                                final AtomicInteger poolNumber = new AtomicInteger(1);
                                final ThreadGroup group;
                                final AtomicInteger threadNumber = new AtomicInteger(1);
                                final String namePrefix;

                                {
                                    SecurityManager securityManager = System.getSecurityManager();
                                    this.group = securityManager != null ? securityManager.getThreadGroup() : Thread.currentThread().getThreadGroup();
                                    this.namePrefix = "tcc-async-terminate-pool-" + poolNumber.getAndIncrement() + "-thread-";
                                }

                                @Override
                                public Thread newThread(Runnable runnable) {
                                    Thread thread = new Thread(this.group, runnable, this.namePrefix + this.threadNumber.getAndIncrement(), 0L);
                                    if (thread.isDaemon()) {
                                        thread.setDaemon(false);
                                    }

                                    if (thread.getPriority() != 5) {
                                        thread.setPriority(5);
                                    }

                                    return thread;
                                }
                            },
                            new ThreadPoolExecutor.CallerRunsPolicy());
                }
            }
        }

        transactionManager.setExecutorService(executorService);

        if (transactionRepository instanceof CachableTransactionRepository) {
            ((CachableTransactionRepository) transactionRepository).setExpireDuration(tylooRecoverConfiguration.getRecoverDuration());
        }
    }

    @Override
    public TransactionManager getTransactionManager() {
        return transactionManager;
    }

    @Override
    public TransactionRepository getTransactionRepository() {
        return transactionRepository;
    }

    @Override
    public TylooRecoverConfiguration getTylooRecoverConfiguration() {
        return tylooRecoverConfiguration;
    }
}


================================================
FILE: tyloo-spring/src/main/resources/tyloo.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:task="http://www.springframework.org/schema/task"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">

    <aop:aspectj-autoproxy proxy-target-class="true"/>

    <bean id="springBeanFactory" class="io.tyloo.spring.support.SpringBeanFactory"/>

    <bean id="transactionConfigurator" class="io.tyloo.spring.support.SpringTransactionConfigurator"
          init-method="init"/>

    <bean id="tylooTransactionAspect" class="io.tyloo.spring.ConfigurableTransactionAspect"
          init-method="init">
        <property name="transactionConfigurator" ref="transactionConfigurator"/>
    </bean>

    <bean id="tylooCoordinatorAspect" class="io.tyloo.spring.ConfigurableCoordinatorAspect"
          init-method="init">
        <property name="transactionConfigurator" ref="transactionConfigurator"/>
    </bean>

    <task:annotation-driven/>


    <bean id="transactionRecovery" class="io.tyloo.recover.TylooTransactionRecovery">
        <property name="transactionConfigurator" ref="transactionConfigurator"/>
    </bean>

    <bean id="recoverScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"/>

    <bean id="recoverScheduledJob" class="io.tyloo.spring.recover.RecoverScheduledJob"
          init-method="init">
        <property name="tylooTransactionRecovery" ref="transactionRecovery"/>
        <property name="transactionConfigurator" ref="transactionConfigurator"/>
        <property name="scheduler" ref="recoverScheduler"/>
    </bean>

</beans>

================================================
FILE: tyloo-tutorial-sample/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>tyloo</artifactId>
        <groupId>io.tyloo</groupId>
        <version>1.1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>tyloo-tutorial-sample</artifactId>
    <packaging>pom</packaging>
    <modules>
        <module>tyloo-dubbo-sample</module>
        <module>tyloo-http-sample</module>
        <module>tyloo-server-sample</module>
        <module>tyloo-sample-domain</module>
    </modules>


</project>

================================================
FILE: tyloo-tutorial-sample/src/tylooSampledb/create_db_cap.sql
================================================
CREATE DATABASE `TCC_CAP` /*!40100 DEFAULT CHARACTER SET utf8 */;
use TCC_CAP;
CREATE TABLE `CAP_CAPITAL_ACCOUNT` (
  `CAPITAL_ACCOUNT_ID` int(11) NOT NULL AUTO_INCREMENT,
  `BALANCE_AMOUNT` decimal(10,0) DEFAULT NULL,
  `USER_ID` int(11) DEFAULT NULL,
  PRIMARY KEY (`CAPITAL_ACCOUNT_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

CREATE TABLE `CAP_TRADE_ORDER` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `SELF_USER_ID` bigint(11) DEFAULT NULL,
  `OPPOSITE_USER_ID` bigint(11) DEFAULT NULL,
  `MERCHANT_ORDER_NO` varchar(45) NOT NULL,
  `AMOUNT` decimal(10,0) DEFAULT NULL,
  `STATUS` varchar(45) DEFAULT NULL,
  `VERSION` int(11) DEFAULT NULL,
  PRIMARY KEY (`ID`),
  UNIQUE KEY `UX_MERCHANT_ORDER_NO` (`MERCHANT_ORDER_NO`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

INSERT INTO `CAP_CAPITAL_ACCOUNT`(CAPITAL_ACCOUNT_ID, BALANCE_AMOUNT, USER_ID) VALUE (1,10000,1000);
INSERT INTO `CAP_CAPITAL_ACCOUNT`(CAPITAL_ACCOUNT_ID, BALANCE_AMOUNT, USER_ID) VALUE (2,10000,2000);

================================================
FILE: tyloo-tutorial-sample/src/tylooSampledb/create_db_ord.sql
================================================
CREATE DATABASE `TCC_ORD` /*!40100 DEFAULT CHARACTER SET utf8 */;
use TCC_ORD;
CREATE TABLE `ORD_ORDER` (
  `ORDER_ID` int(11) NOT NULL AUTO_INCREMENT,
  `PAYER_USER_ID` int(11) DEFAULT NULL,
  `PAYEE_USER_ID` int(11) DEFAULT NULL,
  `RED_PACKET_PAY_AMOUNT` decimal(10,0) DEFAULT NULL,
  `CAPITAL_PAY_AMOUNT` decimal(10,0) DEFAULT NULL,
  `STATUS` varchar(45) DEFAULT NULL,
  `MERCHANT_ORDER_NO` varchar(45) NOT NULL,
  `VERSION` int(11) DEFAULT NULL,
  PRIMARY KEY (`ORDER_ID`),
  UNIQUE KEY `MERCHANT_ORDER_NO_UNIQUE` (`MERCHANT_ORDER_NO`)
) ENGINE=InnoDB AUTO_INCREMENT=1188 DEFAULT CHARSET=utf8;

CREATE TABLE `ORD_ORDER_LINE` (
  `ORDER_LINE_ID` int(11) NOT NULL AUTO_INCREMENT,
  `PRODUCT_ID` int(11) DEFAULT NULL,
  `QUANTITY` decimal(10,0) DEFAULT NULL,
  `UNIT_PRICE` decimal(10,0) DEFAULT NULL,
  PRIMARY KEY (`ORDER_LINE_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

CREATE TABLE `ORD_SHOP` (
  `SHOP_ID` int(11) NOT NULL,
  `OWNER_USER_ID` int(11) DEFAULT NULL,
  PRIMARY KEY (`SHOP_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

CREATE TABLE `ORD_PRODUCT`(
  `PRODUCT_ID` int(11) NOT NULL,
  `SHOP_ID` int(11) NOT NULL,
  `PRODUCT_NAME` VARCHAR(64) DEFAULT NULL ,
  `PRICE` DECIMAL(10,0) DEFAULT NULL,
  PRIMARY KEY (`PRODUCT_ID`)
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;


INSERT INTO `ORD_SHOP` (`SHOP_ID`,`OWNER_USER_ID`) VALUES (1,1000);

INSERT INTO `ORD_PRODUCT` (`PRODUCT_ID`,`SHOP_ID`,`PRODUCT_NAME`,`PRICE`) VALUES (1,1,'IPhone6S',5288);
INSERT INTO `ORD_PRODUCT` (`PRODUCT_ID`,`SHOP_ID`,`PRODUCT_NAME`,`PRICE`) VALUES (2,1,'MAC Pro',10288);
INSERT INTO `ORD_PRODUCT` (`PRODUCT_ID`,`SHOP_ID`,`PRODUCT_NAME`,`PRICE`) VALUES (3,1,'IWatch',2288);

================================================
FILE: tyloo-tutorial-sample/src/tylooSampledb/create_db_red.sql
================================================
CREATE DATABASE `TCC_RED` /*!40100 DEFAULT CHARACTER SET utf8 */;
use TCC_RED;
CREATE TABLE `RED_RED_PACKET_ACCOUNT` (
  `RED_PACKET_ACCOUNT_ID` int(11) NOT NULL,
  `BALANCE_AMOUNT` decimal(10,0) DEFAULT NULL,
  `USER_ID` int(11) DEFAULT NULL,
  PRIMARY KEY (`RED_PACKET_ACCOUNT_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

CREATE TABLE `RED_TRADE_ORDER` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `SELF_USER_ID` bigint(11) DEFAULT NULL,
  `OPPOSITE_USER_ID` bigint(11) DEFAULT NULL,
  `MERCHANT_ORDER_NO` varchar(45) NOT NULL,
  `AMOUNT` decimal(10,0) DEFAULT NULL,
  `STATUS` varchar(45) DEFAULT NULL,
  `VERSION` int(11) DEFAULT NULL,
  PRIMARY KEY (`ID`),
  UNIQUE KEY `MERCHANT_ORDER_NO_UNIQUE` (`MERCHANT_ORDER_NO`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

INSERT INTO `RED_RED_PACKET_ACCOUNT` (`RED_PACKET_ACCOUNT_ID`,`BALANCE_AMOUNT`,`USER_ID`) VALUES (1,950,1000);
INSERT INTO `RED_RED_PACKET_ACCOUNT` (`RED_PACKET_ACCOUNT_ID`,`BALANCE_AMOUNT`,`USER_ID`) VALUES (2,500,2000);


================================================
FILE: tyloo-tutorial-sample/src/tylooSampledb/create_db_tcc.sql
================================================
CREATE DATABASE `TCC` /*!40100 DEFAULT CHARACTER SET utf8 */;
use TCC;
CREATE TABLE `TCC_TRANSACTION_CAP` (
  `TRANSACTION_ID` int(11) NOT NULL AUTO_INCREMENT,
  `DOMAIN` varchar(100) DEFAULT NULL,
  `GLOBAL_TX_ID` varbinary(32) NOT NULL,
  `BRANCH_QUALIFIER` varbinary(32) NOT NULL,
  `CONTENT` varbinary(8000) DEFAULT NULL,
  `STATUS` int(11) DEFAULT NULL,
  `TRANSACTION_TYPE` int(11) DEFAULT NULL,
  `RETRIED_COUNT` int(11) DEFAULT NULL,
  `CREATE_TIME` datetime DEFAULT NULL,
  `LAST_UPDATE_TIME` datetime DEFAULT NULL,
  `VERSION` int(11) DEFAULT NULL,
  PRIMARY KEY (`TRANSACTION_ID`),
  UNIQUE KEY `UX_TX_BQ` (`GLOBAL_TX_ID`,`BRANCH_QUALIFIER`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `TCC_TRANSACTION_CAP` ADD `IS_DELETE` tinyint(1) DEFAULT 0 NOT NULL;

CREATE TABLE `TCC_TRANSACTION_ORD` (
  `TRANSACTION_ID` int(11) NOT NULL AUTO_INCREMENT,
  `DOMAIN` varchar(100) DEFAULT NULL,
  `GLOBAL_TX_ID` varbinary(32) NOT NULL,
  `BRANCH_QUALIFIER` varbinary(32) NOT NULL,
  `CONTENT` varbinary(8000) DEFAULT NULL,
  `STATUS` int(11) DEFAULT NULL,
  `TRANSACTION_TYPE` int(11) DEFAULT NULL,
  `RETRIED_COUNT` int(11) DEFAULT NULL,
  `CREATE_TIME` datetime DEFAULT NULL,
  `LAST_UPDATE_TIME` datetime DEFAULT NULL,
  `VERSION` int(11) DEFAULT NULL,
  PRIMARY KEY (`TRANSACTION_ID`),
  UNIQUE KEY `UX_TX_BQ` (`GLOBAL_TX_ID`,`BRANCH_QUALIFIER`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `TCC_TRANSACTION_ORD` ADD `IS_DELETE` tinyint(1) DEFAULT 0 NOT NULL;

CREATE TABLE `TCC_TRANSACTION_RED` (
  `TRANSACTION_ID` int(11) NOT NULL AUTO_INCREMENT,
  `DOMAIN` varchar(100) DEFAULT NULL,
  `GLOBAL_TX_ID` varbinary(32) NOT NULL,
  `BRANCH_QUALIFIER` varbinary(32) NOT NULL,
  `CONTENT` varbinary(8000) DEFAULT NULL,
  `STATUS` int(11) DEFAULT NULL,
  `TRANSACTION_TYPE` int(11) DEFAULT NULL,
  `RETRIED_COUNT` int(11) DEFAULT NULL,
  `CREATE_TIME` datetime DEFAULT NULL,
  `LAST_UPDATE_TIME` datetime DEFAULT NULL,
  `VERSION` int(11) DEFAULT NULL,
  PRIMARY KEY (`TRANSACTION_ID`),
  UNIQUE KEY `UX_TX_BQ` (`GLOBAL_TX_ID`,`BRANCH_QUALIFIER`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `TCC_TRANSACTION_RED` ADD `IS_DELETE` tinyint(1) DEFAULT 0 NOT NULL;

CREATE TABLE `TCC_TRANSACTION_UT` (
  `TRANSACTION_ID` int(11) NOT NULL AUTO_INCREMENT,
  `DOMAIN` varchar(100) DEFAULT NULL,
  `GLOBAL_TX_ID` varbinary(32) NOT NULL,
  `BRANCH_QUALIFIER` varbinary(32) NOT NULL,
  `CONTENT` varbinary(8000) DEFAULT NULL,
  `STATUS` int(11)
Download .txt
gitextract_mxpupjhz/

├── .gitignore
├── README.md
├── pom.xml
├── tyloo-api/
│   ├── pom.xml
│   └── src/
│       └── main/
│           └── java/
│               └── io/
│                   └── tyloo/
│                       └── api/
│                           ├── Propagation.java
│                           ├── TransactionContext.java
│                           ├── TransactionContextEditor.java
│                           ├── TransactionStatus.java
│                           ├── TransactionXid.java
│                           ├── Tyloo.java
│                           ├── UniqueIdentity.java
│                           └── UuidUtils.java
├── tyloo-core/
│   ├── pom.xml
│   └── src/
│       └── main/
│           └── java/
│               └── io/
│                   └── tyloo/
│                       ├── CancellingException.java
│                       ├── ConcurrentTransactionException.java
│                       ├── ConfirmingException.java
│                       ├── InvocationContext.java
│                       ├── NoExistedTransactionException.java
│                       ├── OptimisticLockException.java
│                       ├── Participant.java
│                       ├── SystemException.java
│                       ├── Terminator.java
│                       ├── Transaction.java
│                       ├── TransactionManager.java
│                       ├── TransactionRepository.java
│                       ├── common/
│                       │   ├── MethodRole.java
│                       │   └── TransactionType.java
│                       ├── context/
│                       │   └── MethodTransactionContextEditor.java
│                       ├── interceptor/
│                       │   ├── TylooCoordinatorAspect.java
│                       │   ├── TylooCoordinatorInterceptor.java
│                       │   ├── TylooMethodContext.java
│                       │   ├── TylooTransactionAspect.java
│                       │   └── TylooTransactionInterceptor.java
│                       ├── recover/
│                       │   ├── TylooRecoverConfiguration.java
│                       │   └── TylooTransactionRecovery.java
│                       ├── repository/
│                       │   ├── CachableTransactionRepository.java
│                       │   ├── FileSystemTransactionRepository.java
│                       │   ├── JdbcTransactionRepository.java
│                       │   ├── RedisTransactionRepository.java
│                       │   ├── TransactionIOException.java
│                       │   └── helper/
│                       │       ├── ExpandTransactionSerializer.java
│                       │       ├── JedisCallback.java
│                       │       ├── RedisHelper.java
│                       │       └── TransactionSerializer.java
│                       ├── serializer/
│                       │   ├── JacksonJsonSerializer.java
│                       │   ├── JdkSerializationSerializer.java
│                       │   ├── KryoPoolSerializer.java
│                       │   └── ObjectSerializer.java
│                       ├── support/
│                       │   ├── BeanFactory.java
│                       │   ├── FactoryBuilder.java
│                       │   └── TransactionConfigurator.java
│                       └── utils/
│                           ├── ByteUtils.java
│                           ├── CollectionUtils.java
│                           ├── ReflectionUtils.java
│                           ├── StringUtils.java
│                           ├── TransactionUtils.java
│                           └── TylooMethodUtils.java
├── tyloo-dubbo/
│   ├── pom.xml
│   └── src/
│       └── main/
│           ├── java/
│           │   └── io/
│           │       └── tyloo/
│           │           └── dubbo/
│           │               ├── constants/
│           │               │   └── TransactionContextConstants.java
│           │               ├── context/
│           │               │   └── DubboTransactionContextEditor.java
│           │               └── proxy/
│           │                   ├── javassist/
│           │                   │   ├── TylooClassGenerator.java
│           │                   │   ├── TylooJavassistProxyFactory.java
│           │                   │   └── TylooProxy.java
│           │                   └── jdk/
│           │                       ├── MethodProceedingJoinPoint.java
│           │                       ├── TylooInvokerInvocationHandler.java
│           │                       └── TylooJdkProxyFactory.java
│           └── resources/
│               ├── META-INF/
│               │   └── dubbo/
│               │       └── org.apache.dubbo.rpc.ProxyFactory
│               └── tyloo-dubbo.xml
├── tyloo-spring/
│   ├── pom.xml
│   └── src/
│       └── main/
│           ├── dbscripts/
│           │   └── db.sql
│           ├── java/
│           │   └── io/
│           │       └── tyloo/
│           │           └── spring/
│           │               ├── ConfigurableCoordinatorAspect.java
│           │               ├── ConfigurableTransactionAspect.java
│           │               ├── recover/
│           │               │   ├── DefaultTylooRecoverConfiguration.java
│           │               │   └── RecoverScheduledJob.java
│           │               ├── repository/
│           │               │   └── SpringJdbcTransactionRepository.java
│           │               └── support/
│           │                   ├── SpringBeanFactory.java
│           │                   ├── SpringPostProcessor.java
│           │                   └── SpringTransactionConfigurator.java
│           └── resources/
│               └── tyloo.xml
├── tyloo-tutorial-sample/
│   ├── pom.xml
│   ├── src/
│   │   └── tylooSampledb/
│   │       ├── create_db_cap.sql
│   │       ├── create_db_ord.sql
│   │       ├── create_db_red.sql
│   │       └── create_db_tcc.sql
│   ├── tyloo-dubbo-sample/
│   │   ├── pom.xml
│   │   ├── src/
│   │   │   └── main/
│   │   │       └── tylooSampledb/
│   │   │           ├── create_db_cap.sql
│   │   │           ├── create_db_ord.sql
│   │   │           ├── create_db_red.sql
│   │   │           └── create_db_tcc.sql
│   │   ├── tyloo-dubbo-capital/
│   │   │   ├── pom.xml
│   │   │   └── src/
│   │   │       └── main/
│   │   │           ├── java/
│   │   │           │   └── io/
│   │   │           │       └── tyloo/
│   │   │           │           └── sample/
│   │   │           │               └── dubbo/
│   │   │           │                   └── capital/
│   │   │           │                       └── service/
│   │   │           │                           ├── CapitalAccountServiceImpl.java
│   │   │           │                           └── CapitalTradeOrderServiceImpl.java
│   │   │           ├── resources/
│   │   │           │   ├── config/
│   │   │           │   │   └── spring/
│   │   │           │   │       └── local/
│   │   │           │   │           ├── appcontext-service-provider.xml
│   │   │           │   │           ├── appcontext-service-tcc.xml
│   │   │           │   │           └── appcontext-web-servlet.xml
│   │   │           │   ├── log/
│   │   │           │   │   └── log4j.xml
│   │   │           │   ├── sample-dubbo-capital.properties
│   │   │           │   └── tccjdbc.properties
│   │   │           └── webapp/
│   │   │               ├── WEB-INF/
│   │   │               │   └── web.xml
│   │   │               └── index.jsp
│   │   ├── tyloo-dubbo-capital-api/
│   │   │   ├── pom.xml
│   │   │   └── src/
│   │   │       └── main/
│   │   │           └── java/
│   │   │               └── io/
│   │   │                   └── tyloo/
│   │   │                       └── sample/
│   │   │                           └── dubbo/
│   │   │                               └── capital/
│   │   │                                   └── api/
│   │   │                                       ├── CapitalAccountService.java
│   │   │                                       ├── CapitalTradeOrderService.java
│   │   │                                       └── dto/
│   │   │                                           └── CapitalTradeOrderDto.java
│   │   ├── tyloo-dubbo-order/
│   │   │   ├── pom.xml
│   │   │   └── src/
│   │   │       └── main/
│   │   │           ├── java/
│   │   │           │   └── io/
│   │   │           │       └── tyloo/
│   │   │           │           └── sample/
│   │   │           │               └── dubbo/
│   │   │           │                   └── order/
│   │   │           │                       ├── service/
│   │   │           │                       │   ├── AccountServiceImpl.java
│   │   │           │                       │   ├── PaymentServiceImpl.java
│   │   │           │                       │   └── PlaceOrderServiceImpl.java
│   │   │           │                       └── web/
│   │   │           │                           └── controller/
│   │   │           │                               ├── OrderController.java
│   │   │           │                               └── vo/
│   │   │           │                                   └── PlaceOrderRequest.java
│   │   │           ├── resources/
│   │   │           │   ├── config/
│   │   │           │   │   └── spring/
│   │   │           │   │       └── local/
│   │   │           │   │           ├── appcontext-service-dubbo.xml
│   │   │           │   │           ├── appcontext-service-tcc.xml
│   │   │           │   │           └── appcontext-web-servlet.xml
│   │   │           │   ├── log/
│   │   │           │   │   └── log4j.xml
│   │   │           │   ├── sample-dubbo-order.properties
│   │   │           │   └── tccjdbc.properties
│   │   │           └── webapp/
│   │   │               └── WEB-INF/
│   │   │                   ├── ftl/
│   │   │                   │   ├── index.ftl
│   │   │                   │   ├── pay_success.ftl
│   │   │                   │   ├── product_detail.ftl
│   │   │                   │   └── shop.ftl
│   │   │                   └── web.xml
│   │   ├── tyloo-dubbo-redpacket/
│   │   │   ├── pom.xml
│   │   │   └── src/
│   │   │       └── main/
│   │   │           ├── java/
│   │   │           │   └── io/
│   │   │           │       └── tyloo/
│   │   │           │           └── sample/
│   │   │           │               └── dubbo/
│   │   │           │                   └── redpacket/
│   │   │           │                       └── service/
│   │   │           │                           ├── RedPacketAccountServiceImpl.java
│   │   │           │                           └── RedPacketTradeOrderServiceImpl.java
│   │   │           ├── resources/
│   │   │           │   ├── config/
│   │   │           │   │   └── spring/
│   │   │           │   │       └── local/
│   │   │           │   │           ├── appcontext-service-provider.xml
│   │   │           │   │           ├── appcontext-service-tcc.xml
│   │   │           │   │           └── appcontext-web-servlet.xml
│   │   │           │   ├── log/
│   │   │           │   │   └── log4j.xml
│   │   │           │   ├── sample-dubbo-redpacket.properties
│   │   │           │   └── tccjdbc.properties
│   │   │           └── webapp/
│   │   │               ├── WEB-INF/
│   │   │               │   └── web.xml
│   │   │               └── index.jsp
│   │   └── tyloo-dubbo-redpacket-api/
│   │       ├── pom.xml
│   │       └── src/
│   │           └── main/
│   │               └── java/
│   │                   └── io/
│   │                       └── tyloo/
│   │                           └── sample/
│   │                               └── dubbo/
│   │                                   └── redpacket/
│   │                                       └── api/
│   │                                           ├── RedPacketAccountService.java
│   │                                           ├── RedPacketTradeOrderService.java
│   │                                           └── dto/
│   │                                               └── RedPacketTradeOrderDto.java
│   ├── tyloo-http-sample/
│   │   ├── pom.xml
│   │   ├── tyloo-http-capital/
│   │   │   ├── pom.xml
│   │   │   └── src/
│   │   │       └── main/
│   │   │           ├── java/
│   │   │           │   └── io/
│   │   │           │       └── tyloo/
│   │   │           │           └── sample/
│   │   │           │               └── http/
│   │   │           │                   └── capital/
│   │   │           │                       └── service/
│   │   │           │                           ├── CapitalAccountServiceImpl.java
│   │   │           │                           └── CapitalTradeOrderServiceImpl.java
│   │   │           ├── resources/
│   │   │           │   ├── config/
│   │   │           │   │   └── spring/
│   │   │           │   │       └── local/
│   │   │           │   │           ├── appcontext-service-provider.xml
│   │   │           │   │           ├── appcontext-service-tcc.xml
│   │   │           │   │           └── appcontext-web-servlet.xml
│   │   │           │   ├── log/
│   │   │           │   │   └── log4j.xml
│   │   │           │   └── tccjdbc.properties
│   │   │           └── webapp/
│   │   │               ├── WEB-INF/
│   │   │               │   └── web.xml
│   │   │               └── index.jsp
│   │   ├── tyloo-http-capital-api/
│   │   │   ├── pom.xml
│   │   │   └── src/
│   │   │       └── main/
│   │   │           └── java/
│   │   │               └── io/
│   │   │                   └── tyloo/
│   │   │                       └── sample/
│   │   │                           └── http/
│   │   │                               └── capital/
│   │   │                                   └── api/
│   │   │                                       ├── CapitalAccountService.java
│   │   │                                       ├── CapitalTradeOrderService.java
│   │   │                                       └── dto/
│   │   │                                           └── CapitalTradeOrderDto.java
│   │   ├── tyloo-http-order/
│   │   │   ├── pom.xml
│   │   │   └── src/
│   │   │       └── main/
│   │   │           ├── java/
│   │   │           │   └── io/
│   │   │           │       └── tyloo/
│   │   │           │           └── sample/
│   │   │           │               └── http/
│   │   │           │                   └── order/
│   │   │           │                       ├── service/
│   │   │           │                       │   ├── AccountServiceImpl.java
│   │   │           │                       │   ├── PaymentServiceImpl.java
│   │   │           │                       │   ├── PlaceOrderServiceImpl.java
│   │   │           │                       │   └── TradeOrderServiceProxy.java
│   │   │           │                       └── web/
│   │   │           │                           └── controller/
│   │   │           │                               ├── OrderController.java
│   │   │           │                               └── vo/
│   │   │           │                                   └── PlaceOrderRequest.java
│   │   │           ├── resources/
│   │   │           │   ├── config/
│   │   │           │   │   └── spring/
│   │   │           │   │       └── local/
│   │   │           │   │           ├── appcontext-service-consumer.xml
│   │   │           │   │           ├── appcontext-service-tcc.xml
│   │   │           │   │           └── appcontext-web-servlet.xml
│   │   │           │   ├── log/
│   │   │           │   │   └── log4j.xml
│   │   │           │   ├── sample-dubbo-order.properties
│   │   │           │   └── tccjdbc.properties
│   │   │           └── webapp/
│   │   │               └── WEB-INF/
│   │   │                   ├── ftl/
│   │   │                   │   ├── index.ftl
│   │   │                   │   ├── pay_success.ftl
│   │   │                   │   ├── product_detail.ftl
│   │   │                   │   └── shop.ftl
│   │   │                   └── web.xml
│   │   ├── tyloo-http-redpacket/
│   │   │   ├── pom.xml
│   │   │   └── src/
│   │   │       └── main/
│   │   │           ├── java/
│   │   │           │   └── io/
│   │   │           │       └── tyloo/
│   │   │           │           └── sample/
│   │   │           │               └── http/
│   │   │           │                   └── redpacket/
│   │   │           │                       └── service/
│   │   │           │                           ├── RedPacketAccountServiceImpl.java
│   │   │           │                           └── RedPacketTradeOrderServiceImpl.java
│   │   │           ├── resources/
│   │   │           │   ├── config/
│   │   │           │   │   └── spring/
│   │   │           │   │       └── local/
│   │   │           │   │           ├── appcontext-service-provider.xml
│   │   │           │   │           ├── appcontext-service-tcc.xml
│   │   │           │   │           └── appcontext-web-servlet.xml
│   │   │           │   ├── log/
│   │   │           │   │   └── log4j.xml
│   │   │           │   └── tccjdbc.properties
│   │   │           └── webapp/
│   │   │               ├── WEB-INF/
│   │   │               │   └── web.xml
│   │   │               └── index.jsp
│   │   └── tyloo-http-redpacket-api/
│   │       ├── pom.xml
│   │       └── src/
│   │           └── main/
│   │               └── java/
│   │                   └── io/
│   │                       └── tyloo/
│   │                           └── sample/
│   │                               └── http/
│   │                                   └── redpacket/
│   │                                       └── api/
│   │                                           ├── RedPacketAccountService.java
│   │                                           ├── RedPacketTradeOrderService.java
│   │                                           └── dto/
│   │                                               └── RedPacketTradeOrderDto.java
│   └── tyloo-sample-domain/
│       ├── pom.xml
│       ├── tyloo-sample-captial/
│       │   ├── pom.xml
│       │   └── src/
│       │       └── main/
│       │           ├── java/
│       │           │   └── io/
│       │           │       └── tyloo/
│       │           │           └── sample/
│       │           │               └── capital/
│       │           │                   ├── domain/
│       │           │                   │   ├── entity/
│       │           │                   │   │   ├── CapitalAccount.java
│       │           │                   │   │   └── TradeOrder.java
│       │           │                   │   └── repository/
│       │           │                   │       ├── CapitalAccountRepository.java
│       │           │                   │       └── TradeOrderRepository.java
│       │           │                   └── infrastructure/
│       │           │                       └── dao/
│       │           │                           ├── CapitalAccountDao.java
│       │           │                           └── TradeOrderDao.java
│       │           └── resources/
│       │               ├── config/
│       │               │   ├── spring/
│       │               │   │   └── local/
│       │               │   │       ├── appcontext-service-dao.xml
│       │               │   │       └── appcontext-service-datasource.xml
│       │               │   └── sqlmap/
│       │               │       └── main/
│       │               │           ├── sample-capitalaccount.xml
│       │               │           └── sample-tradeorder.xml
│       │               ├── jdbc.properties
│       │               └── log/
│       │                   └── log4j.xml
│       ├── tyloo-sample-common/
│       │   ├── pom.xml
│       │   └── src/
│       │       └── main/
│       │           └── java/
│       │               └── io/
│       │                   └── tyloo/
│       │                       └── sample/
│       │                           └── exception/
│       │                               └── InsufficientBalanceException.java
│       ├── tyloo-sample-order/
│       │   ├── pom.xml
│       │   └── src/
│       │       └── main/
│       │           ├── java/
│       │           │   └── io/
│       │           │       └── tyloo/
│       │           │           └── sample/
│       │           │               └── order/
│       │           │                   ├── domain/
│       │           │                   │   ├── entity/
│       │           │                   │   │   ├── Order.java
│       │           │                   │   │   ├── OrderLine.java
│       │           │                   │   │   ├── Product.java
│       │           │                   │   │   └── Shop.java
│       │           │                   │   ├── factory/
│       │           │                   │   │   └── OrderFactory.java
│       │           │                   │   ├── repository/
│       │           │                   │   │   ├── OrderRepository.java
│       │           │                   │   │   ├── ProductRepository.java
│       │           │                   │   │   └── ShopRepository.java
│       │           │                   │   └── service/
│       │           │                   │       └── OrderServiceImpl.java
│       │           │                   └── infrastructure/
│       │           │                       └── dao/
│       │           │                           ├── OrderDao.java
│       │           │                           ├── OrderLineDao.java
│       │           │                           ├── ProductDao.java
│       │           │                           └── ShopDao.java
│       │           └── resources/
│       │               ├── config/
│       │               │   ├── spring/
│       │               │   │   └── local/
│       │               │   │       ├── appcontext-service-dao.xml
│       │               │   │       └── appcontext-service-datasource.xml
│       │               │   └── sqlmap/
│       │               │       └── main/
│       │               │           ├── sample-order.xml
│       │               │           ├── sample-orderline.xml
│       │               │           ├── sample-product.xml
│       │               │           └── sample-shop.xml
│       │               ├── jdbc.properties
│       │               ├── log/
│       │               │   └── log4j.xml
│       │               └── sample-order.properties
│       └── tyloo-sample-redpacket/
│           ├── pom.xml
│           └── src/
│               └── main/
│                   ├── java/
│                   │   └── io/
│                   │       └── tyloo/
│                   │           └── sample/
│                   │               └── redpacket/
│                   │                   ├── domain/
│                   │                   │   ├── entity/
│                   │                   │   │   ├── RedPacketAccount.java
│                   │                   │   │   └── TradeOrder.java
│                   │                   │   └── repository/
│                   │                   │       ├── RedPacketAccountRepository.java
│                   │                   │       └── TradeOrderRepository.java
│                   │                   └── infrastructure/
│                   │                       └── dao/
│                   │                           ├── RedPacketAccountDao.java
│                   │                           └── TradeOrderDao.java
│                   └── resources/
│                       ├── config/
│                       │   ├── spring/
│                       │   │   └── local/
│                       │   │       ├── appcontext-service-dao.xml
│                       │   │       └── appcontext-service-datasource.xml
│                       │   └── sqlmap/
│                       │       └── main/
│                       │           ├── sample-redpacketaccount.xml
│                       │           └── sample-tradeorder.xml
│                       ├── jdbc.properties
│                       └── log/
│                           └── log4j.xml
└── tyloo-unit-test/
    ├── pom.xml
    └── src/
        ├── main/
        │   ├── java/
        │   │   └── io/
        │   │       └── tyloo/
        │   │           └── unittest/
        │   │               ├── client/
        │   │               │   ├── AccountRecordServiceProxy.java
        │   │               │   ├── AccountServiceProxy.java
        │   │               │   └── TransferService.java
        │   │               ├── entity/
        │   │               │   ├── AccountRecord.java
        │   │               │   ├── AccountStatus.java
        │   │               │   ├── SubAccount.java
        │   │               │   └── UserShardingId.java
        │   │               ├── repository/
        │   │               │   ├── AccountRecordRepository.java
        │   │               │   └── SubAccountRepository.java
        │   │               ├── service/
        │   │               │   ├── AccountService.java
        │   │               │   └── AccountServiceImpl.java
        │   │               ├── thirdservice/
        │   │               │   ├── AccountRecordService.java
        │   │               │   └── AccountRecordServiceImpl.java
        │   │               └── utils/
        │   │                   └── UnitTest.java
        │   └── resources/
        │       └── tyloo-unit-test.xml
        └── test/
            ├── java/
            │   └── io/
            │       └── tyloo/
            │           └── unit/
            │               └── test/
            │                   ├── AbstractTestCase.java
            │                   ├── PerformanceTest.java
            │                   ├── ReflectionTest.java
            │                   └── TransferServiceTest.java
            └── resources/
                └── log4j.properties
Download .txt
SYMBOL INDEX (844 symbols across 151 files)

FILE: tyloo-api/src/main/java/io/tyloo/api/Propagation.java
  type Propagation (line 12) | public enum Propagation {
    method Propagation (line 32) | Propagation(int value) {
    method value (line 36) | public int value() {

FILE: tyloo-api/src/main/java/io/tyloo/api/TransactionContext.java
  class TransactionContext (line 15) | public class TransactionContext implements Serializable {
    method TransactionContext (line 25) | public TransactionContext() {
    method TransactionContext (line 29) | public TransactionContext(TransactionXid xid, int status) {
    method setXid (line 34) | public void setXid(TransactionXid xid) {
    method getXid (line 38) | public TransactionXid getXid() throws CloneNotSupportedException {
    method setAttachments (line 42) | public void setAttachments(Map<String, String> attachments) {
    method getAttachments (line 48) | public Map<String, String> getAttachments() {
    method setStatus (line 52) | public void setStatus(int status) {
    method getStatus (line 56) | public int getStatus() {

FILE: tyloo-api/src/main/java/io/tyloo/api/TransactionContextEditor.java
  type TransactionContextEditor (line 14) | public interface TransactionContextEditor {
    method get (line 24) | TransactionContext get(Object target, Method method, Object[] args);
    method set (line 33) | void set(TransactionContext transactionContext, Object target, Method ...

FILE: tyloo-api/src/main/java/io/tyloo/api/TransactionStatus.java
  type TransactionStatus (line 11) | public enum TransactionStatus {
    method TransactionStatus (line 30) | TransactionStatus(int id) {
    method getId (line 34) | public int getId() {
    method valueOf (line 38) | public static TransactionStatus valueOf(int id) {

FILE: tyloo-api/src/main/java/io/tyloo/api/TransactionXid.java
  class TransactionXid (line 18) | public class TransactionXid implements Xid, Serializable {
    method TransactionXid (line 39) | public TransactionXid() {
    method setGlobalTransactionId (line 44) | public void setGlobalTransactionId(byte[] globalTransactionId) {
    method setBranchQualifier (line 48) | public void setBranchQualifier(byte[] branchQualifier) {
    method TransactionXid (line 52) | public TransactionXid(Object uniqueIdentity) {
    method TransactionXid (line 67) | public TransactionXid(byte[] globalTransactionId) {
    method TransactionXid (line 72) | public TransactionXid(byte[] globalTransactionId, byte[] branchQualifi...
    method getFormatId (line 80) | @Override
    method getGlobalTransactionId (line 88) | @Override
    method getBranchQualifier (line 96) | @Override
    method toString (line 101) | @Override
    method clone (line 119) | @Override
    method hashCode (line 140) | @Override
    method equals (line 150) | @Override
    method uuidToByteArray (line 156) | private static byte[] uuidToByteArray(UUID uuid) {

FILE: tyloo-api/src/main/java/io/tyloo/api/Tyloo.java
  class DefaultTransactionContextEditor (line 58) | class DefaultTransactionContextEditor implements TransactionContextEditor {
    method get (line 60) | @Override
    method set (line 71) | @Override
    method getTransactionContextParamPosition (line 86) | static int getTransactionContextParamPosition(Class<?>[] parameterType...
    method getTransactionContextFromArgs (line 103) | public static TransactionContext getTransactionContextFromArgs(Object[...

FILE: tyloo-api/src/main/java/io/tyloo/api/UuidUtils.java
  class UuidUtils (line 14) | public class UuidUtils {
    method uuidToByteArray (line 16) | public static byte[] uuidToByteArray(UUID uuid) {
    method byteArrayToUUID (line 23) | public static UUID byteArrayToUUID(byte[] bytes) {

FILE: tyloo-core/src/main/java/io/tyloo/CancellingException.java
  class CancellingException (line 9) | public class CancellingException extends RuntimeException {
    method CancellingException (line 12) | public CancellingException(Throwable cause) {

FILE: tyloo-core/src/main/java/io/tyloo/ConcurrentTransactionException.java
  class ConcurrentTransactionException (line 9) | public class ConcurrentTransactionException extends RuntimeException {
    method ConcurrentTransactionException (line 12) | public ConcurrentTransactionException() {
    method ConcurrentTransactionException (line 16) | public ConcurrentTransactionException(String message) {
    method ConcurrentTransactionException (line 20) | public ConcurrentTransactionException(String message, Throwable e) {

FILE: tyloo-core/src/main/java/io/tyloo/ConfirmingException.java
  class ConfirmingException (line 9) | public class ConfirmingException extends RuntimeException {
    method ConfirmingException (line 11) | public ConfirmingException(Throwable cause) {

FILE: tyloo-core/src/main/java/io/tyloo/InvocationContext.java
  class InvocationContext (line 15) | public class InvocationContext implements Serializable {
    method InvocationContext (line 39) | public InvocationContext() {
    method InvocationContext (line 43) | public InvocationContext(Class targetClass, String methodName, Class[]...
    method getArgs (line 50) | public Object[] getArgs() {
    method getTargetClass (line 54) | public Class getTargetClass() {
    method getMethodName (line 58) | public String getMethodName() {
    method getParameterTypes (line 62) | public Class[] getParameterTypes() {

FILE: tyloo-core/src/main/java/io/tyloo/NoExistedTransactionException.java
  class NoExistedTransactionException (line 9) | public class NoExistedTransactionException extends Exception {

FILE: tyloo-core/src/main/java/io/tyloo/OptimisticLockException.java
  class OptimisticLockException (line 9) | public class OptimisticLockException extends RuntimeException {

FILE: tyloo-core/src/main/java/io/tyloo/Participant.java
  class Participant (line 19) | public class Participant implements Serializable {
    method Participant (line 31) | public Participant() {
    method Participant (line 35) | public Participant(TransactionXid xid, InvocationContext confirmInvoca...
    method Participant (line 42) | public Participant(InvocationContext confirmInvocationContext, Invocat...
    method setXid (line 48) | public void setXid(TransactionXid xid) {
    method rollback (line 52) | public void rollback() {
    method commit (line 56) | public void commit() {
    method getXid (line 60) | public TransactionXid getXid() {
    method getConfirmInvocationContext (line 64) | public InvocationContext getConfirmInvocationContext() {
    method getCancelInvocationContext (line 68) | public InvocationContext getCancelInvocationContext() {

FILE: tyloo-core/src/main/java/io/tyloo/SystemException.java
  class SystemException (line 9) | public class SystemException extends RuntimeException {
    method SystemException (line 11) | public SystemException(String message) {
    method SystemException (line 15) | public SystemException(Throwable e) {
    method SystemException (line 19) | public SystemException(String message, Throwable e) {

FILE: tyloo-core/src/main/java/io/tyloo/Terminator.java
  class Terminator (line 19) | public final class Terminator {
    method Terminator (line 21) | public Terminator() {
    method invoke (line 30) | public static void invoke(TransactionContext transactionContext, Invoc...

FILE: tyloo-core/src/main/java/io/tyloo/Transaction.java
  class Transaction (line 24) | public class Transaction implements Serializable  {
    method Transaction (line 46) | public Transaction() {
    method Transaction (line 50) | public Transaction(TransactionContext transactionContext) throws Clone...
    method Transaction (line 56) | public Transaction(TransactionType transactionType) {
    method Transaction (line 62) | public Transaction(Object uniqueIdentity,TransactionType transactionTy...
    method enlistParticipant (line 69) | public void enlistParticipant(Participant participant) {
    method getXid (line 73) | public Xid getXid() {
    method getStatus (line 82) | public TransactionStatus getStatus() {
    method getParticipants (line 87) | public List<Participant> getParticipants() {
    method getTransactionType (line 91) | public TransactionType getTransactionType() {
    method changeStatus (line 95) | public void changeStatus(TransactionStatus status) {
    method commit (line 100) | public void commit() {
    method rollback (line 107) | public void rollback() {
    method getRetriedCount (line 113) | public int getRetriedCount() {
    method addRetriedCount (line 117) | public void addRetriedCount() {
    method resetRetriedCount (line 121) | public void resetRetriedCount(int retriedCount) {
    method getAttachments (line 125) | public Map<String, Object> getAttachments() {
    method getVersion (line 129) | public long getVersion() {
    method updateVersion (line 133) | public void updateVersion() {
    method setVersion (line 137) | public void setVersion(long version) {
    method getLastUpdateTime (line 141) | public Date getLastUpdateTime() {
    method setLastUpdateTime (line 145) | public void setLastUpdateTime(Date date) {
    method getCreateTime (line 149) | public Date getCreateTime() {
    method updateTime (line 153) | public void updateTime() {

FILE: tyloo-core/src/main/java/io/tyloo/TransactionManager.java
  class TransactionManager (line 21) | public class TransactionManager {
    method setTransactionRepository (line 34) | public void setTransactionRepository(TransactionRepository transaction...
    method setExecutorService (line 38) | public void setExecutorService(ExecutorService executorService) {
    method TransactionManager (line 42) | public TransactionManager() {
    method begin (line 56) | public Transaction begin(Object uniqueIdentify) throws CloneNotSupport...
    method propagationNewBegin (line 70) | public Transaction propagationNewBegin(TransactionContext transactionC...
    method propagationExistBegin (line 86) | public Transaction propagationExistBegin(TransactionContext transactio...
    method commit (line 103) | public void commit(boolean asyncCommit) {
    method rollback (line 132) | public void rollback(boolean asyncRollback) {
    method commitTransaction (line 159) | private void commitTransaction(Transaction transaction) {
    method rollbackTransaction (line 169) | private void rollbackTransaction(Transaction transaction) {
    method getCurrentTransaction (line 184) | public Transaction getCurrentTransaction() {
    method isTransactionActive (line 191) | public boolean isTransactionActive() {
    method registerTransaction (line 201) | private void registerTransaction(Transaction transaction) {
    method cleanAfterCompletion (line 215) | public void cleanAfterCompletion(Transaction transaction) {
    method enlistParticipant (line 234) | public void enlistParticipant(Participant participant) {

FILE: tyloo-core/src/main/java/io/tyloo/TransactionRepository.java
  type TransactionRepository (line 20) | public interface TransactionRepository {
    method create (line 22) | int create(Transaction transaction) throws CloneNotSupportedException;
    method update (line 24) | int update(Transaction transaction);
    method delete (line 26) | int delete(Transaction transaction);
    method findByXid (line 28) | Transaction findByXid(TransactionXid xid);
    method findAllUnmodifiedSince (line 30) | List<Transaction> findAllUnmodifiedSince(Date date);

FILE: tyloo-core/src/main/java/io/tyloo/common/MethodRole.java
  type MethodRole (line 10) | public enum MethodRole {

FILE: tyloo-core/src/main/java/io/tyloo/common/TransactionType.java
  type TransactionType (line 11) | public enum TransactionType {
    method TransactionType (line 25) | TransactionType(int id) {
    method valueOf (line 29) | public static TransactionType valueOf(int id) {
    method getId (line 40) | public int getId() {

FILE: tyloo-core/src/main/java/io/tyloo/context/MethodTransactionContextEditor.java
  class MethodTransactionContextEditor (line 16) | @Deprecated
    method get (line 19) | @Override
    method set (line 30) | @Override

FILE: tyloo-core/src/main/java/io/tyloo/interceptor/TylooCoordinatorAspect.java
  class TylooCoordinatorAspect (line 17) | @Aspect
    method transactionContextCall (line 22) | @Pointcut("@annotation(io.tyloo.api.Tyloo)")
    method interceptTransactionContextMethod (line 27) | @Around("transactionContextCall()")
    method setTylooCoordinatorInterceptor (line 32) | public void setTylooCoordinatorInterceptor(TylooCoordinatorInterceptor...
    method getOrder (line 36) | public abstract int getOrder();

FILE: tyloo-core/src/main/java/io/tyloo/interceptor/TylooCoordinatorInterceptor.java
  class TylooCoordinatorInterceptor (line 28) | public class TylooCoordinatorInterceptor {
    method setTransactionManager (line 32) | public void setTransactionManager(TransactionManager transactionManage...
    method interceptTransactionContextMethod (line 36) | public Object interceptTransactionContextMethod(ProceedingJoinPoint pj...
    method enlistParticipant (line 63) | private void enlistParticipant(ProceedingJoinPoint pjp) throws Illegal...

FILE: tyloo-core/src/main/java/io/tyloo/interceptor/TylooMethodContext.java
  class TylooMethodContext (line 22) | public class TylooMethodContext {
    method TylooMethodContext (line 49) | TylooMethodContext(ProceedingJoinPoint pjp) {
    method getAnnotation (line 59) | public Tyloo getAnnotation() {
    method getPropagation (line 63) | public Propagation getPropagation() {
    method getTransactionContext (line 67) | public TransactionContext getTransactionContext() {
    method getMethod (line 71) | public Method getMethod() {
    method getUniqueIdentity (line 80) | public Object getUniqueIdentity() {
    method getTylooMethod (line 102) | private Method getTylooMethod() {
    method getMethodRole (line 121) | public MethodRole getMethodRole(boolean isTransactionActive) {
    method proceed (line 133) | public Object proceed() throws Throwable {

FILE: tyloo-core/src/main/java/io/tyloo/interceptor/TylooTransactionAspect.java
  class TylooTransactionAspect (line 16) | @Aspect
    method setTylooTransactionInterceptor (line 21) | public void setTylooTransactionInterceptor(TylooTransactionInterceptor...
    method tylooService (line 25) | @Pointcut("@annotation(io.tyloo.api.Tyloo)")
    method interceptTylooMethod (line 30) | @Around("tylooService()")
    method getOrder (line 36) | public abstract int getOrder();

FILE: tyloo-core/src/main/java/io/tyloo/interceptor/TylooTransactionInterceptor.java
  class TylooTransactionInterceptor (line 27) | public class TylooTransactionInterceptor {
    method setTransactionManager (line 38) | public void setTransactionManager(TransactionManager transactionManage...
    method setDelayCancelExceptions (line 42) | public void setDelayCancelExceptions(Set<Class<? extends Exception>> d...
    method interceptTylooMethod (line 52) | public Object interceptTylooMethod(ProceedingJoinPoint pjp) throws Thr...
    method rootMethodProceed (line 76) | private Object rootMethodProceed(TylooMethodContext tylooMethodContext...
    method providerMethodProceed (line 113) | private Object providerMethodProceed(TylooMethodContext tylooMethodCon...
    method isDelayCancelException (line 152) | private boolean isDelayCancelException(Throwable throwable, Set<Class<...

FILE: tyloo-core/src/main/java/io/tyloo/recover/TylooRecoverConfiguration.java
  type TylooRecoverConfiguration (line 13) | public interface TylooRecoverConfiguration {
    method getMaxRetryCount (line 20) | int getMaxRetryCount();
    method getRecoverDuration (line 27) | int getRecoverDuration();
    method getCronExpression (line 34) | String getCronExpression();
    method getDelayCancelExceptions (line 41) | Set<Class<? extends Exception>> getDelayCancelExceptions();
    method setDelayCancelExceptions (line 43) | void setDelayCancelExceptions(Set<Class<? extends Exception>> delayRec...
    method getAsyncTerminateThreadCorePoolSize (line 45) | int getAsyncTerminateThreadCorePoolSize();
    method getAsyncTerminateThreadMaxPoolSize (line 47) | int getAsyncTerminateThreadMaxPoolSize();
    method getAsyncTerminateThreadWorkQueueSize (line 49) | int getAsyncTerminateThreadWorkQueueSize();

FILE: tyloo-core/src/main/java/io/tyloo/recover/TylooTransactionRecovery.java
  class TylooTransactionRecovery (line 27) | public class TylooTransactionRecovery {
    method startRecover (line 39) | public void startRecover() throws CloneNotSupportedException {
    method loadErrorTransactions (line 50) | private List<Transaction> loadErrorTransactions() {
    method recoverErrorTransactions (line 62) | private void recoverErrorTransactions(List<Transaction> transactions) ...
    method setTransactionConfigurator (line 110) | public void setTransactionConfigurator(TransactionConfigurator transac...

FILE: tyloo-core/src/main/java/io/tyloo/repository/CachableTransactionRepository.java
  class CachableTransactionRepository (line 25) | public abstract class CachableTransactionRepository implements Transacti...
    method CachableTransactionRepository (line 36) | public CachableTransactionRepository() {
    method create (line 43) | @Override
    method update (line 58) | @Override
    method delete (line 83) | @Override
    method findByXid (line 104) | @Override
    method findAllUnmodifiedSince (line 123) | @Override
    method putToCache (line 138) | protected void putToCache(Transaction transaction) {
    method removeFromCache (line 147) | protected void removeFromCache(Transaction transaction) {
    method findFromCache (line 157) | protected Transaction findFromCache(TransactionXid transactionXid) {
    method setExpireDuration (line 161) | public void setExpireDuration(int durationInSeconds) {
    method doCreate (line 171) | protected abstract int doCreate(Transaction transaction) throws CloneN...
    method doUpdate (line 173) | protected abstract int doUpdate(Transaction transaction) throws CloneN...
    method doDelete (line 175) | protected abstract int doDelete(Transaction transaction) throws CloneN...
    method doFindOne (line 177) | protected abstract Transaction doFindOne(Xid xid);
    method doFindAllUnmodifiedSince (line 179) | protected abstract List<Transaction> doFindAllUnmodifiedSince(Date date);

FILE: tyloo-core/src/main/java/io/tyloo/repository/FileSystemTransactionRepository.java
  class FileSystemTransactionRepository (line 23) | public class FileSystemTransactionRepository extends CachableTransaction...
    method setSerializer (line 31) | public void setSerializer(ObjectSerializer serializer) {
    method setRootPath (line 35) | public void setRootPath(String rootPath) {
    method doCreate (line 39) | @Override
    method doUpdate (line 44) | @Override
    method doDelete (line 54) | @Override
    method doFindOne (line 65) | @Override
    method doFindAllUnmodifiedSince (line 78) | @Override
    method doFindAll (line 95) | protected List<Transaction> doFindAll() {
    method getFullFileName (line 109) | private String getFullFileName(Xid xid) {
    method makeDirIfNecessary (line 113) | private void makeDirIfNecessary() {
    method createFile (line 136) | private int createFile(Transaction transaction) throws CloneNotSupport...
    method writeFile (line 186) | private void writeFile(Transaction transaction) throws CloneNotSupport...
    method readTransaction (line 224) | private Transaction readTransaction(File file) {

FILE: tyloo-core/src/main/java/io/tyloo/repository/JdbcTransactionRepository.java
  class JdbcTransactionRepository (line 26) | public class JdbcTransactionRepository extends CachableTransactionReposi...
    method getDomain (line 36) | public String getDomain() {
    method setDomain (line 40) | public void setDomain(String domain) {
    method getTbSuffix (line 44) | public String getTbSuffix() {
    method setTbSuffix (line 48) | public void setTbSuffix(String tbSuffix) {
    method setSerializer (line 52) | public void setSerializer(ObjectSerializer<Transaction> serializer) {
    method getDataSource (line 56) | public DataSource getDataSource() {
    method setDataSource (line 60) | public void setDataSource(DataSource dataSource) {
    method doCreate (line 64) | @Override
    method doUpdate (line 110) | @Override
    method doDelete (line 159) | @Override
    method doFindOne (line 187) | @Override
    method doFindAllUnmodifiedSince (line 198) | @Override
    method doFind (line 238) | protected List<Transaction> doFind(List<Xid> xids) {
    method constructTransactions (line 292) | protected void constructTransactions(ResultSet resultSet, List<Transac...
    method getConnection (line 305) | protected Connection getConnection() {
    method releaseConnection (line 313) | protected void releaseConnection(Connection con) {
    method closeStatement (line 323) | private void closeStatement(Statement stmt) {
    method getTableName (line 333) | private String getTableName() {

FILE: tyloo-core/src/main/java/io/tyloo/repository/RedisTransactionRepository.java
  class RedisTransactionRepository (line 24) | public class RedisTransactionRepository extends CachableTransactionRepos...
    method setKeyPrefix (line 39) | public void setKeyPrefix(String keyPrefix) {
    method setSerializer (line 43) | public void setSerializer(ObjectSerializer serializer) {
    method getFetchKeySize (line 47) | public int getFetchKeySize() {
    method setFetchKeySize (line 51) | public void setFetchKeySize(int fetchKeySize) {
    method getJedisPool (line 55) | public JedisPool getJedisPool() {
    method setJedisPool (line 59) | public void setJedisPool(JedisPool jedisPool) {
    method setSupportScan (line 73) | public void setSupportScan(boolean isSupportScan) {
    method setForbiddenKeys (line 77) | public void setForbiddenKeys(boolean forbiddenKeys) {
    method doCreate (line 81) | @Override
    method doUpdate (line 106) | @Override
    method doDelete (line 135) | @Override
    method doFindOne (line 147) | @Override
    method doFindAllUnmodifiedSince (line 164) | @Override
    method doFindAll (line 180) | protected List<Transaction> doFindAll() {

FILE: tyloo-core/src/main/java/io/tyloo/repository/TransactionIOException.java
  class TransactionIOException (line 11) | public class TransactionIOException extends RuntimeException {
    method TransactionIOException (line 15) | public TransactionIOException(String message) {
    method TransactionIOException (line 19) | public TransactionIOException(Throwable e) {

FILE: tyloo-core/src/main/java/io/tyloo/repository/helper/ExpandTransactionSerializer.java
  class ExpandTransactionSerializer (line 25) | public class ExpandTransactionSerializer {
    method serialize (line 27) | public static Map<byte[], byte[]> serialize(ObjectSerializer serialize...
    method deserialize (line 44) | public static Transaction deserialize(ObjectSerializer serializer, Map...

FILE: tyloo-core/src/main/java/io/tyloo/repository/helper/JedisCallback.java
  type JedisCallback (line 13) | public interface JedisCallback<T> {
    method doInJedis (line 20) | public T doInJedis(Jedis jedis) throws CloneNotSupportedException;

FILE: tyloo-core/src/main/java/io/tyloo/repository/helper/RedisHelper.java
  class RedisHelper (line 20) | public class RedisHelper {
    method getRedisKey (line 28) | public static byte[] getRedisKey(String keyPrefix, Xid xid) {
    method getRedisKey (line 32) | public static byte[] getRedisKey(String keyPrefix, String globalTransa...
    method execute (line 43) | public static <T> T execute(JedisPool jedisPool, JedisCallback<T> call...
    method buildDefaultScanParams (line 88) | public static ScanParams buildDefaultScanParams(String pattern, int co...
    method isSupportScanCommand (line 98) | public static Boolean isSupportScanCommand(Jedis jedis) {

FILE: tyloo-core/src/main/java/io/tyloo/repository/helper/TransactionSerializer.java
  class TransactionSerializer (line 19) | public class TransactionSerializer {
    method serialize (line 21) | public static byte[] serialize(ObjectSerializer serializer, Transactio...
    method deserialize (line 37) | public static Transaction deserialize(ObjectSerializer serializer, byt...

FILE: tyloo-core/src/main/java/io/tyloo/serializer/JacksonJsonSerializer.java
  class JacksonJsonSerializer (line 21) | public class JacksonJsonSerializer implements ObjectSerializer<Transacti...
    method serialize (line 34) | @Override
    method deserialize (line 43) | @Override
    method clone (line 52) | @Override

FILE: tyloo-core/src/main/java/io/tyloo/serializer/JdkSerializationSerializer.java
  class JdkSerializationSerializer (line 13) | public class JdkSerializationSerializer implements ObjectSerializer<Tran...
    method serialize (line 15) | @Override
    method deserialize (line 20) | @Override
    method clone (line 29) | @Override

FILE: tyloo-core/src/main/java/io/tyloo/serializer/KryoPoolSerializer.java
  class KryoPoolSerializer (line 22) | public class KryoPoolSerializer implements ObjectSerializer<Transaction> {
    method KryoPoolSerializer (line 41) | public KryoPoolSerializer() {
    method KryoPoolSerializer (line 45) | public KryoPoolSerializer(int initPoolSize) {
    method init (line 50) | private void init() {
    method serialize (line 58) | @Override
    method deserialize (line 72) | @Override
    method clone (line 83) | @Override

FILE: tyloo-core/src/main/java/io/tyloo/serializer/ObjectSerializer.java
  type ObjectSerializer (line 9) | public interface ObjectSerializer<T> {
    method serialize (line 17) | byte[] serialize(T t);
    method deserialize (line 25) | T deserialize(byte[] bytes);
    method clone (line 28) | T clone(T object);

FILE: tyloo-core/src/main/java/io/tyloo/support/BeanFactory.java
  type BeanFactory (line 12) | public interface BeanFactory {
    method getBean (line 13) | <T> T getBean(Class<T> var1);
    method isFactoryOf (line 15) | <T> boolean isFactoryOf(Class<T> clazz);

FILE: tyloo-core/src/main/java/io/tyloo/support/FactoryBuilder.java
  class FactoryBuilder (line 15) | public final class FactoryBuilder {
    method FactoryBuilder (line 18) | private FactoryBuilder() {
    method factoryOf (line 39) | public static <T> SingeltonFactory<T> factoryOf(Class<T> clazz) {
    method registerBeanFactory (line 60) | public static void registerBeanFactory(BeanFactory beanFactory) {
    class SingeltonFactory (line 69) | public static class SingeltonFactory<T> {
      method SingeltonFactory (line 75) | public SingeltonFactory(Class<T> clazz, T instance) {
      method SingeltonFactory (line 80) | public SingeltonFactory(Class<T> clazz) {
      method getInstance (line 89) | public T getInstance() {
      method equals (line 107) | @Override
      method hashCode (line 121) | @Override

FILE: tyloo-core/src/main/java/io/tyloo/support/TransactionConfigurator.java
  type TransactionConfigurator (line 16) | public interface TransactionConfigurator {
    method getTransactionManager (line 23) | TransactionManager getTransactionManager();
    method getTransactionRepository (line 30) | TransactionRepository getTransactionRepository();
    method getTylooRecoverConfiguration (line 37) | TylooRecoverConfiguration getTylooRecoverConfiguration();

FILE: tyloo-core/src/main/java/io/tyloo/utils/ByteUtils.java
  class ByteUtils (line 9) | public class ByteUtils {
    method longToBytes (line 11) | public static byte[] longToBytes(long num) {
    method bytesToLong (line 15) | public static long bytesToLong(byte[] bytes) {
    method intToBytes (line 19) | public static byte[] intToBytes(int num) {
    method bytesToInt (line 23) | public static int bytesToInt(byte[] bytes) {

FILE: tyloo-core/src/main/java/io/tyloo/utils/CollectionUtils.java
  class CollectionUtils (line 11) | public final class CollectionUtils {
    method CollectionUtils (line 13) | private CollectionUtils() {
    method isEmpty (line 17) | public static boolean isEmpty(Collection collection) {

FILE: tyloo-core/src/main/java/io/tyloo/utils/ReflectionUtils.java
  class ReflectionUtils (line 16) | public class ReflectionUtils {
    method makeAccessible (line 19) | public static void makeAccessible(Method method) {
    method changeAnnotationValue (line 26) | public static Object changeAnnotationValue(Annotation annotation, Stri...
    method getDeclaringType (line 42) | public static Class getDeclaringType(Class aClass, String methodName, ...
    method getNullValue (line 63) | public static Object getNullValue(Class type) {

FILE: tyloo-core/src/main/java/io/tyloo/utils/StringUtils.java
  class StringUtils (line 9) | public class StringUtils {
    method isNotEmpty (line 11) | public static boolean isNotEmpty(String value) {

FILE: tyloo-core/src/main/java/io/tyloo/utils/TransactionUtils.java
  class TransactionUtils (line 12) | public class TransactionUtils {
    method isLegalTransactionContext (line 14) | public static boolean isLegalTransactionContext(boolean isTransactionA...

FILE: tyloo-core/src/main/java/io/tyloo/utils/TylooMethodUtils.java
  class TylooMethodUtils (line 18) | public class TylooMethodUtils {
    method getTylooMethod (line 20) | public static Method getTylooMethod(ProceedingJoinPoint pjp) {
    method calculateMethodType (line 33) | public static MethodRole calculateMethodType(Propagation propagation, ...
    method getTransactionContextParamPosition (line 45) | public static int getTransactionContextParamPosition(Class<?>[] parame...

FILE: tyloo-dubbo/src/main/java/io/tyloo/dubbo/constants/TransactionContextConstants.java
  class TransactionContextConstants (line 13) | public class TransactionContextConstants {

FILE: tyloo-dubbo/src/main/java/io/tyloo/dubbo/context/DubboTransactionContextEditor.java
  class DubboTransactionContextEditor (line 24) | public class DubboTransactionContextEditor implements TransactionContext...
    method get (line 25) | @Override
    method set (line 37) | @Override

FILE: tyloo-dubbo/src/main/java/io/tyloo/dubbo/proxy/javassist/TylooClassGenerator.java
  class TylooClassGenerator (line 33) | public final class TylooClassGenerator {
    method TylooClassGenerator (line 47) | private TylooClassGenerator() {
    method TylooClassGenerator (line 50) | private TylooClassGenerator(ClassPool pool) {
    method newInstance (line 54) | public static TylooClassGenerator newInstance() {
    method newInstance (line 58) | public static TylooClassGenerator newInstance(ClassLoader loader) {
    method isDynamicClass (line 62) | public static boolean isDynamicClass(Class<?> cl) {
    method getClassPool (line 66) | public static ClassPool getClassPool(ClassLoader loader) {
    method modifier (line 80) | private static String modifier(int mod) {
    method getClassName (line 93) | public String getClassName() {
    method setClassName (line 97) | public TylooClassGenerator setClassName(String name) {
    method addInterface (line 102) | public TylooClassGenerator addInterface(String cn) {
    method addInterface (line 110) | public TylooClassGenerator addInterface(Class<?> cl) {
    method setSuperClass (line 114) | public TylooClassGenerator setSuperClass(String cn) {
    method setSuperClass (line 119) | public TylooClassGenerator setSuperClass(Class<?> cl) {
    method addField (line 124) | public TylooClassGenerator addField(String code) {
    method addField (line 132) | public TylooClassGenerator addField(String name, int mod, Class<?> typ...
    method addField (line 136) | public TylooClassGenerator addField(String name, int mod, Class<?> typ...
    method addMethod (line 148) | public TylooClassGenerator addMethod(String code) {
    method addMethod (line 156) | public TylooClassGenerator addMethod(String name, int mod, Class<?> rt...
    method addMethod (line 160) | public TylooClassGenerator addMethod(boolean isTylooMethod, String nam...
    method addMethod (line 191) | public TylooClassGenerator addMethod(Method m) {
    method addMethod (line 196) | public TylooClassGenerator addMethod(String name, Method m) {
    method addConstructor (line 206) | public TylooClassGenerator addConstructor(String code) {
    method addConstructor (line 214) | public TylooClassGenerator addConstructor(int mod, Class<?>[] pts, Str...
    method addConstructor (line 218) | public TylooClassGenerator addConstructor(int mod, Class<?>[] pts, Cla...
    method addConstructor (line 243) | public TylooClassGenerator addConstructor(Constructor<?> c) {
    method addDefaultConstructor (line 253) | public TylooClassGenerator addDefaultConstructor() {
    method getClassPool (line 258) | public ClassPool getClassPool() {
    method toClass (line 262) | public Class<?> toClass() {
    method release (line 343) | public void release() {
    method getCtClass (line 367) | private CtClass getCtClass(Class<?> c) throws NotFoundException {
    method getCtMethod (line 371) | private CtMethod getCtMethod(Method m) throws NotFoundException {
    method getCtConstructor (line 375) | private CtConstructor getCtConstructor(Constructor<?> c) throws NotFou...
    type DC (line 379) | public interface DC {

FILE: tyloo-dubbo/src/main/java/io/tyloo/dubbo/proxy/javassist/TylooJavassistProxyFactory.java
  class TylooJavassistProxyFactory (line 15) | public class TylooJavassistProxyFactory extends JavassistProxyFactory {
    method getProxy (line 26) | @Override

FILE: tyloo-dubbo/src/main/java/io/tyloo/dubbo/proxy/javassist/TylooProxy.java
  class TylooProxy (line 43) | public abstract class TylooProxy {
    method invoke (line 45) | @Override
    method TylooProxy (line 59) | protected TylooProxy() {
    method getProxy (line 68) | public static TylooProxy getProxy(Class<?>... ics) {
    method getProxy (line 84) | public static TylooProxy getProxy(ClassLoader cl, Class<?>... ics) {
    method asArgument (line 249) | private static String asArgument(Class<?> cl, String name) {
    method newInstance (line 285) | public Object newInstance() {
    method newInstance (line 294) | abstract public Object newInstance(InvocationHandler handler);

FILE: tyloo-dubbo/src/main/java/io/tyloo/dubbo/proxy/jdk/MethodProceedingJoinPoint.java
  class MethodProceedingJoinPoint (line 29) | public class MethodProceedingJoinPoint implements ProceedingJoinPoint, J...
    method MethodProceedingJoinPoint (line 52) | public MethodProceedingJoinPoint(Object proxy, Object target, Method m...
    method set$AroundClosure (line 65) | @Override
    method proceed (line 70) | @Override
    method proceed (line 89) | @Override
    method toShortString (line 106) | @Override
    method toLongString (line 111) | @Override
    method toString (line 116) | @Override
    method getThis (line 121) | @Override
    method getTarget (line 126) | @Override
    method getArgs (line 131) | @Override
    method getSignature (line 136) | @Override
    method getSourceLocation (line 144) | @Override
    method getKind (line 152) | @Override
    method getId (line 157) | @Override
    method getStaticPart (line 162) | @Override
    class MethodSignatureImpl (line 170) | private class MethodSignatureImpl implements MethodSignature {
      method getName (line 174) | @Override
      method getModifiers (line 179) | @Override
      method getDeclaringType (line 184) | @Override
      method getDeclaringTypeName (line 189) | @Override
      method getReturnType (line 194) | @Override
      method getMethod (line 199) | @Override
      method getParameterTypes (line 204) | @Override
      method getParameterNames (line 209) | @Override
      method getExceptionTypes (line 214) | @Override
      method toShortString (line 219) | @Override
      method toLongString (line 224) | @Override
      method toString (line 229) | @Override
      method toString (line 234) | private String toString(boolean includeModifier, boolean includeRetu...
      method appendTypes (line 255) | private void appendTypes(StringBuilder sb, Class<?>[] types,
      method appendType (line 271) | private void appendType(StringBuilder sb, Class<?> type, boolean use...
    class SourceLocationImpl (line 285) | private class SourceLocationImpl implements SourceLocation {
      method getWithinType (line 287) | @Override
      method getFileName (line 295) | @Override
      method getLine (line 300) | @Override
      method getColumn (line 305) | @Override

FILE: tyloo-dubbo/src/main/java/io/tyloo/dubbo/proxy/jdk/TylooInvokerInvocationHandler.java
  class TylooInvokerInvocationHandler (line 26) | public class TylooInvokerInvocationHandler extends InvokerInvocationHand...
    method TylooInvokerInvocationHandler (line 30) | public TylooInvokerInvocationHandler(Invoker<?> handler) {
    method TylooInvokerInvocationHandler (line 34) | public <T> TylooInvokerInvocationHandler(T target, Invoker<T> invoker) {
    method invoke (line 39) | @Override

FILE: tyloo-dubbo/src/main/java/io/tyloo/dubbo/proxy/jdk/TylooJdkProxyFactory.java
  class TylooJdkProxyFactory (line 19) | public class TylooJdkProxyFactory extends JdkProxyFactory {
    method getProxy (line 30) | @Override

FILE: tyloo-spring/src/main/dbscripts/db.sql
  type `TCC_TRANSACTION` (line 1) | CREATE TABLE `TCC_TRANSACTION` (

FILE: tyloo-spring/src/main/java/io/tyloo/spring/ConfigurableCoordinatorAspect.java
  class ConfigurableCoordinatorAspect (line 18) | @Aspect
    method init (line 27) | public void init() {
    method getOrder (line 34) | @Override
    method setTransactionConfigurator (line 39) | public void setTransactionConfigurator(TransactionConfigurator transac...

FILE: tyloo-spring/src/main/java/io/tyloo/spring/ConfigurableTransactionAspect.java
  class ConfigurableTransactionAspect (line 18) | @Aspect
    method init (line 27) | public void init() {
    method getOrder (line 38) | @Override
    method setTransactionConfigurator (line 43) | public void setTransactionConfigurator(TransactionConfigurator transac...

FILE: tyloo-spring/src/main/java/io/tyloo/spring/recover/DefaultTylooRecoverConfiguration.java
  class DefaultTylooRecoverConfiguration (line 20) | @AllArgsConstructor
    method DefaultTylooRecoverConfiguration (line 56) | public DefaultTylooRecoverConfiguration() {
    method setDelayCancelExceptions (line 76) | @Override

FILE: tyloo-spring/src/main/java/io/tyloo/spring/recover/RecoverScheduledJob.java
  class RecoverScheduledJob (line 20) | public class RecoverScheduledJob {
    method init (line 40) | public void init() {
    method setTylooTransactionRecovery (line 82) | public void setTylooTransactionRecovery(TylooTransactionRecovery tyloo...
    method getScheduler (line 86) | public Scheduler getScheduler() {
    method setScheduler (line 90) | public void setScheduler(Scheduler scheduler) {
    method setTransactionConfigurator (line 94) | public void setTransactionConfigurator(TransactionConfigurator transac...

FILE: tyloo-spring/src/main/java/io/tyloo/spring/repository/SpringJdbcTransactionRepository.java
  class SpringJdbcTransactionRepository (line 18) | public class SpringJdbcTransactionRepository extends JdbcTransactionRepo...
    method getConnection (line 20) | @Override
    method releaseConnection (line 25) | @Override

FILE: tyloo-spring/src/main/java/io/tyloo/spring/support/SpringBeanFactory.java
  class SpringBeanFactory (line 20) | public class SpringBeanFactory implements BeanFactory, ApplicationContex...
    method setApplicationContext (line 24) | @Override
    method isFactoryOf (line 30) | @Override
    method getBean (line 36) | @Override

FILE: tyloo-spring/src/main/java/io/tyloo/spring/support/SpringPostProcessor.java
  class SpringPostProcessor (line 18) | public class SpringPostProcessor implements ApplicationListener<ContextR...
    method onApplicationEvent (line 22) | @Override

FILE: tyloo-spring/src/main/java/io/tyloo/spring/support/SpringTransactionConfigurator.java
  class SpringTransactionConfigurator (line 22) | public class SpringTransactionConfigurator implements TransactionConfigu...
    method init (line 35) | public void init() {
    method getTransactionManager (line 88) | @Override
    method getTransactionRepository (line 93) | @Override
    method getTylooRecoverConfiguration (line 98) | @Override

FILE: tyloo-tutorial-sample/src/tylooSampledb/create_db_cap.sql
  type `CAP_CAPITAL_ACCOUNT` (line 3) | CREATE TABLE `CAP_CAPITAL_ACCOUNT` (
  type `CAP_TRADE_ORDER` (line 10) | CREATE TABLE `CAP_TRADE_ORDER` (

FILE: tyloo-tutorial-sample/src/tylooSampledb/create_db_ord.sql
  type `ORD_ORDER` (line 3) | CREATE TABLE `ORD_ORDER` (
  type `ORD_ORDER_LINE` (line 16) | CREATE TABLE `ORD_ORDER_LINE` (
  type `ORD_SHOP` (line 24) | CREATE TABLE `ORD_SHOP` (
  type `ORD_PRODUCT` (line 30) | CREATE TABLE `ORD_PRODUCT`(

FILE: tyloo-tutorial-sample/src/tylooSampledb/create_db_red.sql
  type `RED_RED_PACKET_ACCOUNT` (line 3) | CREATE TABLE `RED_RED_PACKET_ACCOUNT` (
  type `RED_TRADE_ORDER` (line 10) | CREATE TABLE `RED_TRADE_ORDER` (

FILE: tyloo-tutorial-sample/src/tylooSampledb/create_db_tcc.sql
  type `TCC_TRANSACTION_CAP` (line 3) | CREATE TABLE `TCC_TRANSACTION_CAP` (
  type `TCC_TRANSACTION_ORD` (line 21) | CREATE TABLE `TCC_TRANSACTION_ORD` (
  type `TCC_TRANSACTION_RED` (line 39) | CREATE TABLE `TCC_TRANSACTION_RED` (
  type `TCC_TRANSACTION_UT` (line 57) | CREATE TABLE `TCC_TRANSACTION_UT` (

FILE: tyloo-tutorial-sample/tyloo-dubbo-sample/src/main/tylooSampledb/create_db_cap.sql
  type `CAP_CAPITAL_ACCOUNT` (line 5) | CREATE TABLE `CAP_CAPITAL_ACCOUNT` (
  type `CAP_TRADE_ORDER` (line 12) | CREATE TABLE `CAP_TRADE_ORDER` (

FILE: tyloo-tutorial-sample/tyloo-dubbo-sample/src/main/tylooSampledb/create_db_ord.sql
  type `ORD_ORDER` (line 5) | CREATE TABLE `ORD_ORDER` (
  type `ORD_ORDER_LINE` (line 16) | CREATE TABLE `ORD_ORDER_LINE` (
  type `ORD_SHOP` (line 24) | CREATE TABLE `ORD_SHOP` (
  type `ORD_PRODUCT` (line 30) | CREATE TABLE `ORD_PRODUCT`(

FILE: tyloo-tutorial-sample/tyloo-dubbo-sample/src/main/tylooSampledb/create_db_red.sql
  type `RED_RED_PACKET_ACCOUNT` (line 3) | CREATE TABLE `RED_RED_PACKET_ACCOUNT` (
  type `RED_TRADE_ORDER` (line 10) | CREATE TABLE `RED_TRADE_ORDER` (

FILE: tyloo-tutorial-sample/tyloo-dubbo-sample/src/main/tylooSampledb/create_db_tcc.sql
  type `TCC_TRANSACTION_CAP` (line 5) | CREATE TABLE `TCC_TRANSACTION_CAP` (
  type `TCC_TRANSACTION_ORD` (line 21) | CREATE TABLE `TCC_TRANSACTION_ORD` (
  type `TCC_TRANSACTION_RED` (line 37) | CREATE TABLE `TCC_TRANSACTION_RED` (
  type `TCC_TRANSACTION_UT` (line 54) | CREATE TABLE `TCC_TRANSACTION_UT` (

FILE: tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-capital-api/src/main/java/io/tyloo/sample/dubbo/capital/api/CapitalAccountService.java
  type CapitalAccountService (line 6) | public interface CapitalAccountService {
    method getCapitalAccountByUserId (line 8) | BigDecimal getCapitalAccountByUserId(long userId);

FILE: tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-capital-api/src/main/java/io/tyloo/sample/dubbo/capital/api/CapitalTradeOrderService.java
  type CapitalTradeOrderService (line 7) | public interface CapitalTradeOrderService {
    method record (line 9) | @Tyloo

FILE: tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-capital-api/src/main/java/io/tyloo/sample/dubbo/capital/api/dto/CapitalTradeOrderDto.java
  class CapitalTradeOrderDto (line 7) | public class CapitalTradeOrderDto implements Serializable {
    method getSelfUserId (line 21) | public long getSelfUserId() {
    method setSelfUserId (line 25) | public void setSelfUserId(long selfUserId) {
    method getOppositeUserId (line 29) | public long getOppositeUserId() {
    method setOppositeUserId (line 33) | public void setOppositeUserId(long oppositeUserId) {
    method getOrderTitle (line 37) | public String getOrderTitle() {
    method setOrderTitle (line 41) | public void setOrderTitle(String orderTitle) {
    method getMerchantOrderNo (line 45) | public String getMerchantOrderNo() {
    method setMerchantOrderNo (line 49) | public void setMerchantOrderNo(String merchantOrderNo) {
    method getAmount (line 53) | public BigDecimal getAmount() {
    method setAmount (line 57) | public void setAmount(BigDecimal amount) {

FILE: tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-capital/src/main/java/io/tyloo/sample/dubbo/capital/service/CapitalAccountServiceImpl.java
  class CapitalAccountServiceImpl (line 10) | @Service("capitalAccountService")
    method getCapitalAccountByUserId (line 17) | @Override

FILE: tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-capital/src/main/java/io/tyloo/sample/dubbo/capital/service/CapitalTradeOrderServiceImpl.java
  class CapitalTradeOrderServiceImpl (line 20) | @Service("capitalTradeOrderService")
    method record (line 29) | @Override
    method confirmRecord (line 73) | @Transactional
    method cancelRecord (line 97) | @Transactional

FILE: tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-order/src/main/java/io/tyloo/sample/dubbo/order/service/AccountServiceImpl.java
  class AccountServiceImpl (line 11) | @Service("accountService")
    method getRedPacketAccountByUserId (line 21) | public BigDecimal getRedPacketAccountByUserId(long userId){
    method getCapitalAccountByUserId (line 25) | public BigDecimal getCapitalAccountByUserId(long userId){

FILE: tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-order/src/main/java/io/tyloo/sample/dubbo/order/service/PaymentServiceImpl.java
  class PaymentServiceImpl (line 21) | @Service
    method makePayment (line 33) | @Tyloo(confirmMethod = "confirmMakePayment", cancelMethod = "cancelMak...
    method confirmMakePayment (line 52) | public void confirmMakePayment(String orderNo, BigDecimal redPacketPay...
    method cancelMakePayment (line 72) | public void cancelMakePayment(String orderNo,  BigDecimal redPacketPay...
    method buildCapitalTradeOrderDto (line 92) | private CapitalTradeOrderDto buildCapitalTradeOrderDto(Order order) {
    method buildRedPacketTradeOrderDto (line 104) | private RedPacketTradeOrderDto buildRedPacketTradeOrderDto(Order order) {

FILE: tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-order/src/main/java/io/tyloo/sample/dubbo/order/service/PlaceOrderServiceImpl.java
  class PlaceOrderServiceImpl (line 17) | @Service
    method placeOrder (line 29) | public String placeOrder(long payerUserId, long shopId, List<Pair<Long...

FILE: tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-order/src/main/java/io/tyloo/sample/dubbo/order/web/controller/OrderController.java
  class OrderController (line 25) | @Controller
    method index (line 41) | @RequestMapping(value = "/", method = RequestMethod.GET)
    method getProductsInShop (line 47) | @RequestMapping(value = "/user/{userId}/shop/{shopId}", method = Reque...
    method productDetail (line 61) | @RequestMapping(value = "/user/{userId}/shop/{shopId}/product/{product...
    method placeOrder (line 79) | @RequestMapping(value = "/placeorder", method = RequestMethod.POST)
    method getPayResult (line 94) | @RequestMapping(value = "/payresult/{merchantOrderNo}", method = Reque...
    method buildRequest (line 113) | private PlaceOrderRequest buildRequest(String redPacketPayAmount, long...

FILE: tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-order/src/main/java/io/tyloo/sample/dubbo/order/web/controller/vo/PlaceOrderRequest.java
  class PlaceOrderRequest (line 10) | public class PlaceOrderRequest {
    method getPayerUserId (line 20) | public long getPayerUserId() {
    method setPayerUserId (line 24) | public void setPayerUserId(long payerUserId) {
    method getShopId (line 28) | public long getShopId() {
    method setShopId (line 32) | public void setShopId(long shopId) {
    method getRedPacketPayAmount (line 36) | public BigDecimal getRedPacketPayAmount() {
    method setRedPacketPayAmount (line 40) | public void setRedPacketPayAmount(BigDecimal redPacketPayAmount) {
    method getProductQuantities (line 44) | public List<Pair<Long, Integer>> getProductQuantities() {
    method setProductQuantities (line 48) | public void setProductQuantities(List<Pair<Long, Integer>> productQuan...

FILE: tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-redpacket-api/src/main/java/io/tyloo/sample/dubbo/redpacket/api/RedPacketAccountService.java
  type RedPacketAccountService (line 6) | public interface RedPacketAccountService {
    method getRedPacketAccountByUserId (line 7) | BigDecimal getRedPacketAccountByUserId(long userId);

FILE: tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-redpacket-api/src/main/java/io/tyloo/sample/dubbo/redpacket/api/RedPacketTradeOrderService.java
  type RedPacketTradeOrderService (line 7) | public interface RedPacketTradeOrderService {
    method record (line 9) | @Tyloo

FILE: tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-redpacket-api/src/main/java/io/tyloo/sample/dubbo/redpacket/api/dto/RedPacketTradeOrderDto.java
  class RedPacketTradeOrderDto (line 7) | public class RedPacketTradeOrderDto implements Serializable {
    method getSelfUserId (line 21) | public long getSelfUserId() {
    method setSelfUserId (line 25) | public void setSelfUserId(long selfUserId) {
    method getOppositeUserId (line 29) | public long getOppositeUserId() {
    method setOppositeUserId (line 33) | public void setOppositeUserId(long oppositeUserId) {
    method getOrderTitle (line 37) | public String getOrderTitle() {
    method setOrderTitle (line 41) | public void setOrderTitle(String orderTitle) {
    method getMerchantOrderNo (line 45) | public String getMerchantOrderNo() {
    method setMerchantOrderNo (line 49) | public void setMerchantOrderNo(String merchantOrderNo) {
    method getAmount (line 53) | public BigDecimal getAmount() {
    method setAmount (line 57) | public void setAmount(BigDecimal amount) {

FILE: tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-redpacket/src/main/java/io/tyloo/sample/dubbo/redpacket/service/RedPacketAccountServiceImpl.java
  class RedPacketAccountServiceImpl (line 11) | @Service("redPacketAccountService")
    method getRedPacketAccountByUserId (line 17) | @Override

FILE: tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-redpacket/src/main/java/io/tyloo/sample/dubbo/redpacket/service/RedPacketTradeOrderServiceImpl.java
  class RedPacketTradeOrderServiceImpl (line 20) | @Service("redPacketTradeOrderService")
    method record (line 29) | @Override
    method confirmRecord (line 71) | @Transactional
    method cancelRecord (line 97) | @Transactional

FILE: tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-capital-api/src/main/java/io/tyloo/sample/http/capital/api/CapitalAccountService.java
  type CapitalAccountService (line 5) | public interface CapitalAccountService {
    method getCapitalAccountByUserId (line 7) | BigDecimal getCapitalAccountByUserId(long userId);

FILE: tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-capital-api/src/main/java/io/tyloo/sample/http/capital/api/CapitalTradeOrderService.java
  type CapitalTradeOrderService (line 7) | public interface CapitalTradeOrderService {
    method record (line 8) | public String record(TransactionContext transactionContext, CapitalTra...

FILE: tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-capital-api/src/main/java/io/tyloo/sample/http/capital/api/dto/CapitalTradeOrderDto.java
  class CapitalTradeOrderDto (line 7) | public class CapitalTradeOrderDto implements Serializable {
    method getSelfUserId (line 21) | public long getSelfUserId() {
    method setSelfUserId (line 25) | public void setSelfUserId(long selfUserId) {
    method getOppositeUserId (line 29) | public long getOppositeUserId() {
    method setOppositeUserId (line 33) | public void setOppositeUserId(long oppositeUserId) {
    method getOrderTitle (line 37) | public String getOrderTitle() {
    method setOrderTitle (line 41) | public void setOrderTitle(String orderTitle) {
    method getMerchantOrderNo (line 45) | public String getMerchantOrderNo() {
    method setMerchantOrderNo (line 49) | public void setMerchantOrderNo(String merchantOrderNo) {
    method getAmount (line 53) | public BigDecimal getAmount() {
    method setAmount (line 57) | public void setAmount(BigDecimal amount) {

FILE: tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-capital/src/main/java/io/tyloo/sample/http/capital/service/CapitalAccountServiceImpl.java
  class CapitalAccountServiceImpl (line 10) | public class CapitalAccountServiceImpl implements CapitalAccountService {
    method getCapitalAccountByUserId (line 16) | @Override

FILE: tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-capital/src/main/java/io/tyloo/sample/http/capital/service/CapitalTradeOrderServiceImpl.java
  class CapitalTradeOrderServiceImpl (line 20) | public class CapitalTradeOrderServiceImpl implements CapitalTradeOrderSe...
    method record (line 28) | @Override
    method confirmRecord (line 69) | @Transactional
    method cancelRecord (line 95) | @Transactional

FILE: tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-order/src/main/java/io/tyloo/sample/http/order/service/AccountServiceImpl.java
  class AccountServiceImpl (line 11) | @Service("accountService")
    method getRedPacketAccountByUserId (line 21) | public BigDecimal getRedPacketAccountByUserId(long userId){
    method getCapitalAccountByUserId (line 25) | public BigDecimal getCapitalAccountByUserId(long userId){

FILE: tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-order/src/main/java/io/tyloo/sample/http/order/service/PaymentServiceImpl.java
  class PaymentServiceImpl (line 18) | @Service
    method makePayment (line 28) | @Tyloo(confirmMethod = "confirmMakePayment", cancelMethod = "cancelMak...
    method confirmMakePayment (line 49) | public void confirmMakePayment(Order order, BigDecimal redPacketPayAmo...
    method cancelMakePayment (line 69) | public void cancelMakePayment(Order order, BigDecimal redPacketPayAmou...
    method buildCapitalTradeOrderDto (line 89) | private CapitalTradeOrderDto buildCapitalTradeOrderDto(Order order) {
    method buildRedPacketTradeOrderDto (line 101) | private RedPacketTradeOrderDto buildRedPacketTradeOrderDto(Order order) {

FILE: tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-order/src/main/java/io/tyloo/sample/http/order/service/PlaceOrderServiceImpl.java
  class PlaceOrderServiceImpl (line 17) | @Service
    method placeOrder (line 30) | public String placeOrder(long payerUserId, long shopId, List<Pair<Long...

FILE: tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-order/src/main/java/io/tyloo/sample/http/order/service/TradeOrderServiceProxy.java
  class TradeOrderServiceProxy (line 15) | @Component
    method record (line 27) | @Tyloo(propagation = Propagation.SUPPORTS, confirmMethod = "record", c...
    method record (line 32) | @Tyloo(propagation = Propagation.SUPPORTS, confirmMethod = "record", c...

FILE: tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-order/src/main/java/io/tyloo/sample/http/order/web/controller/OrderController.java
  class OrderController (line 25) | @Controller
    method index (line 41) | @RequestMapping(value = "/", method = RequestMethod.GET)
    method getProductsInShop (line 47) | @RequestMapping(value = "/user/{userId}/shop/{shopId}", method = Reque...
    method productDetail (line 61) | @RequestMapping(value = "/user/{userId}/shop/{shopId}/product/{product...
    method placeOrder (line 79) | @RequestMapping(value = "/placeorder", method = RequestMethod.POST)
    method getPayResult (line 94) | @RequestMapping(value = "/payresult/{merchantOrderNo}", method = Reque...
    method buildRequest (line 114) | private PlaceOrderRequest buildRequest(String redPacketPayAmount, long...

FILE: tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-order/src/main/java/io/tyloo/sample/http/order/web/controller/vo/PlaceOrderRequest.java
  class PlaceOrderRequest (line 10) | public class PlaceOrderRequest {
    method getPayerUserId (line 20) | public long getPayerUserId() {
    method setPayerUserId (line 24) | public void setPayerUserId(long payerUserId) {
    method getShopId (line 28) | public long getShopId() {
    method setShopId (line 32) | public void setShopId(long shopId) {
    method getRedPacketPayAmount (line 36) | public BigDecimal getRedPacketPayAmount() {
    method setRedPacketPayAmount (line 40) | public void setRedPacketPayAmount(BigDecimal redPacketPayAmount) {
    method getProductQuantities (line 44) | public List<Pair<Long, Integer>> getProductQuantities() {
    method setProductQuantities (line 48) | public void setProductQuantities(List<Pair<Long, Integer>> productQuan...

FILE: tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-redpacket-api/src/main/java/io/tyloo/sample/http/redpacket/api/RedPacketAccountService.java
  type RedPacketAccountService (line 6) | public interface RedPacketAccountService {
    method getRedPacketAccountByUserId (line 7) | BigDecimal getRedPacketAccountByUserId(long userId);

FILE: tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-redpacket-api/src/main/java/io/tyloo/sample/http/redpacket/api/RedPacketTradeOrderService.java
  type RedPacketTradeOrderService (line 7) | public interface RedPacketTradeOrderService {
    method record (line 9) | public String record(TransactionContext transactionContext, RedPacketT...

FILE: tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-redpacket-api/src/main/java/io/tyloo/sample/http/redpacket/api/dto/RedPacketTradeOrderDto.java
  class RedPacketTradeOrderDto (line 7) | public class RedPacketTradeOrderDto implements Serializable {
    method getSelfUserId (line 21) | public long getSelfUserId() {
    method setSelfUserId (line 25) | public void setSelfUserId(long selfUserId) {
    method getOppositeUserId (line 29) | public long getOppositeUserId() {
    method setOppositeUserId (line 33) | public void setOppositeUserId(long oppositeUserId) {
    method getOrderTitle (line 37) | public String getOrderTitle() {
    method setOrderTitle (line 41) | public void setOrderTitle(String orderTitle) {
    method getMerchantOrderNo (line 45) | public String getMerchantOrderNo() {
    method setMerchantOrderNo (line 49) | public void setMerchantOrderNo(String merchantOrderNo) {
    method getAmount (line 53) | public BigDecimal getAmount() {
    method setAmount (line 57) | public void setAmount(BigDecimal amount) {

FILE: tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-redpacket/src/main/java/io/tyloo/sample/http/redpacket/service/RedPacketAccountServiceImpl.java
  class RedPacketAccountServiceImpl (line 10) | public class RedPacketAccountServiceImpl implements RedPacketAccountServ...
    method getRedPacketAccountByUserId (line 15) | @Override

FILE: tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-redpacket/src/main/java/io/tyloo/sample/http/redpacket/service/RedPacketTradeOrderServiceImpl.java
  class RedPacketTradeOrderServiceImpl (line 20) | public class RedPacketTradeOrderServiceImpl implements RedPacketTradeOrd...
    method record (line 28) | @Override
    method confirmRecord (line 70) | @Transactional
    method cancelRecord (line 95) | @Transactional

FILE: tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-captial/src/main/java/io/tyloo/sample/capital/domain/entity/CapitalAccount.java
  class CapitalAccount (line 10) | public class CapitalAccount {
    method getUserId (line 20) | public long getUserId() {
    method getBalanceAmount (line 24) | public BigDecimal getBalanceAmount() {
    method getId (line 29) | public long getId() {
    method setId (line 33) | public void setId(long id) {
    method transferFrom (line 37) | public void transferFrom(BigDecimal amount) {
    method transferTo (line 48) | public void transferTo(BigDecimal amount) {
    method cancelTransfer (line 53) | public void cancelTransfer(BigDecimal amount) {

FILE: tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-captial/src/main/java/io/tyloo/sample/capital/domain/entity/TradeOrder.java
  class TradeOrder (line 5) | public class TradeOrder {
    method TradeOrder (line 21) | public TradeOrder() {
    method TradeOrder (line 24) | public TradeOrder(long selfUserId, long oppositeUserId, String merchan...
    method getId (line 31) | public long getId() {
    method getSelfUserId (line 35) | public long getSelfUserId() {
    method getOppositeUserId (line 39) | public long getOppositeUserId() {
    method getMerchantOrderNo (line 43) | public String getMerchantOrderNo() {
    method getAmount (line 47) | public BigDecimal getAmount() {
    method getStatus (line 51) | public String getStatus() {
    method confirm (line 55) | public void confirm() {
    method cancel (line 59) | public void cancel() {
    method getVersion (line 63) | public long getVersion() {
    method updateVersion (line 67) | public void updateVersion() {

FILE: tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-captial/src/main/java/io/tyloo/sample/capital/domain/repository/CapitalAccountRepository.java
  class CapitalAccountRepository (line 10) | @Repository
    method findByUserId (line 16) | public CapitalAccount findByUserId(long userId) {
    method save (line 21) | public void save(CapitalAccount capitalAccount) {

FILE: tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-captial/src/main/java/io/tyloo/sample/capital/domain/repository/TradeOrderRepository.java
  class TradeOrderRepository (line 10) | @Repository
    method insert (line 16) | public void insert(TradeOrder tradeOrder) {
    method update (line 20) | public void update(TradeOrder tradeOrder) {
    method findByMerchantOrderNo (line 28) | public TradeOrder findByMerchantOrderNo(String merchantOrderNo) {

FILE: tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-captial/src/main/java/io/tyloo/sample/capital/infrastructure/dao/CapitalAccountDao.java
  type CapitalAccountDao (line 6) | public interface CapitalAccountDao {
    method findByUserId (line 8) | CapitalAccount findByUserId(long userId);
    method update (line 10) | int update(CapitalAccount capitalAccount);

FILE: tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-captial/src/main/java/io/tyloo/sample/capital/infrastructure/dao/TradeOrderDao.java
  type TradeOrderDao (line 7) | public interface TradeOrderDao {
    method insert (line 9) | int insert(TradeOrder tradeOrder);
    method update (line 11) | int update(TradeOrder tradeOrder);
    method findByMerchantOrderNo (line 13) | TradeOrder findByMerchantOrderNo(String merchantOrderNo);

FILE: tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-common/src/main/java/io/tyloo/sample/exception/InsufficientBalanceException.java
  class InsufficientBalanceException (line 4) | public class InsufficientBalanceException extends RuntimeException {
    method InsufficientBalanceException (line 7) | public InsufficientBalanceException() {
    method InsufficientBalanceException (line 11) | public InsufficientBalanceException(String message) {

FILE: tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-order/src/main/java/io/tyloo/sample/order/domain/entity/Order.java
  class Order (line 11) | public class Order implements Serializable {
    method Order (line 32) | public Order() {
    method Order (line 36) | public Order(long payerUserId, long payeeUserId) {
    method getPayerUserId (line 42) | public long getPayerUserId() {
    method getPayeeUserId (line 46) | public long getPayeeUserId() {
    method getTotalAmount (line 50) | public BigDecimal getTotalAmount() {
    method addOrderLine (line 61) | public void addOrderLine(OrderLine orderLine) {
    method getOrderLines (line 65) | public List<OrderLine> getOrderLines() {
    method pay (line 69) | public void pay(BigDecimal redPacketPayAmount, BigDecimal capitalPayAm...
    method getRedPacketPayAmount (line 75) | public BigDecimal getRedPacketPayAmount() {
    method getCapitalPayAmount (line 79) | public BigDecimal getCapitalPayAmount() {
    method getMerchantOrderNo (line 83) | public String getMerchantOrderNo() {
    method setMerchantOrderNo (line 87) | public void setMerchantOrderNo(String merchantOrderNo) {
    method getId (line 91) | public long getId() {
    method getStatus (line 95) | public String getStatus() {
    method confirm (line 99) | public void confirm() {
    method cancelPayment (line 103) | public void cancelPayment() {
    method getVersion (line 108) | public long getVersion() {
    method updateVersion (line 112) | public void updateVersion() {

FILE: tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-order/src/main/java/io/tyloo/sample/order/domain/entity/OrderLine.java
  class OrderLine (line 7) | public class OrderLine implements Serializable {
    method OrderLine (line 18) | public OrderLine() {
    method OrderLine (line 22) | public OrderLine(Long productId, Integer quantity,BigDecimal unitPrice) {
    method getProductId (line 28) | public long getProductId() {
    method getQuantity (line 32) | public int getQuantity() {
    method getUnitPrice (line 36) | public BigDecimal getUnitPrice() {
    method getTotalAmount (line 40) | public BigDecimal getTotalAmount() {
    method getId (line 44) | public long getId() {

FILE: tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-order/src/main/java/io/tyloo/sample/order/domain/entity/Product.java
  class Product (line 7) | public class Product implements Serializable{
    method Product (line 16) | public Product() {
    method Product (line 19) | public Product(long productId, long shopId, String productName, BigDec...
    method getProductId (line 26) | public long getProductId() {
    method getShopId (line 30) | public long getShopId() {
    method getProductName (line 34) | public String getProductName() {
    method getPrice (line 38) | public BigDecimal getPrice() {

FILE: tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-order/src/main/java/io/tyloo/sample/order/domain/entity/Shop.java
  class Shop (line 4) | public class Shop {
    method getOwnerUserId (line 10) | public long getOwnerUserId() {
    method getId (line 14) | public long getId() {

FILE: tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-order/src/main/java/io/tyloo/sample/order/domain/factory/OrderFactory.java
  class OrderFactory (line 13) | @Component
    method buildOrder (line 19) | public Order buildOrder(long payerUserId, long payeeUserId, List<Pair<...

FILE: tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-order/src/main/java/io/tyloo/sample/order/domain/repository/OrderRepository.java
  class OrderRepository (line 18) | @Repository
    method createOrder (line 27) | public void createOrder(Order order) {
    method updateOrder (line 35) | public void updateOrder(Order order) {
    method findByMerchantOrderNo (line 44) | public Order findByMerchantOrderNo(String merchantOrderNo) {

FILE: tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-order/src/main/java/io/tyloo/sample/order/domain/repository/ProductRepository.java
  class ProductRepository (line 11) | @Repository
    method findById (line 17) | public Product findById(long productId){
    method findByShopId (line 21) | public List<Product> findByShopId(long shopId){

FILE: tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-order/src/main/java/io/tyloo/sample/order/domain/repository/ShopRepository.java
  class ShopRepository (line 9) | @Repository
    method findById (line 15) | public Shop findById(long id) {

FILE: tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-order/src/main/java/io/tyloo/sample/order/domain/service/OrderServiceImpl.java
  class OrderServiceImpl (line 14) | @Service
    method createOrder (line 23) | @Transactional
    method findOrderByMerchantOrderNo (line 32) | public Order findOrderByMerchantOrderNo(String orderNo) {

FILE: tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-order/src/main/java/io/tyloo/sample/order/infrastructure/dao/OrderDao.java
  type OrderDao (line 6) | public interface OrderDao {
    method insert (line 8) | public int insert(Order order);
    method update (line 10) | public int update(Order order);
    method findByMerchantOrderNo (line 12) | Order findByMerchantOrderNo(String merchantOrderNo);

FILE: tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-order/src/main/java/io/tyloo/sample/order/infrastructure/dao/OrderLineDao.java
  type OrderLineDao (line 7) | public interface OrderLineDao {
    method insert (line 8) | void insert(OrderLine orderLine);

FILE: tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-order/src/main/java/io/tyloo/sample/order/infrastructure/dao/ProductDao.java
  type ProductDao (line 9) | public interface ProductDao {
    method findById (line 11) | Product findById(long productId);
    method findByShopId (line 13) | List<Product> findByShopId(long shopId);

FILE: tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-order/src/main/java/io/tyloo/sample/order/infrastructure/dao/ShopDao.java
  type ShopDao (line 7) | public interface ShopDao {
    method findById (line 8) | Shop findById(long id);

FILE: tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-redpacket/src/main/java/io/tyloo/sample/redpacket/domain/entity/RedPacketAccount.java
  class RedPacketAccount (line 8) | public class RedPacketAccount {
    method getUserId (line 16) | public long getUserId() {
    method getBalanceAmount (line 20) | public BigDecimal getBalanceAmount() {
    method getId (line 25) | public long getId() {
    method setId (line 29) | public void setId(long id) {
    method transferFrom (line 33) | public void transferFrom(BigDecimal amount) {
    method transferTo (line 41) | public void transferTo(BigDecimal amount) {
    method cancelTransfer (line 45) | public void cancelTransfer(BigDecimal amount) {

FILE: tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-redpacket/src/main/java/io/tyloo/sample/redpacket/domain/entity/TradeOrder.java
  class TradeOrder (line 5) | public class TradeOrder {
    method TradeOrder (line 21) | public TradeOrder() {
    method TradeOrder (line 24) | public TradeOrder(long selfUserId, long oppositeUserId, String merchan...
    method getId (line 31) | public long getId() {
    method getSelfUserId (line 35) | public long getSelfUserId() {
    method getOppositeUserId (line 39) | public long getOppositeUserId() {
    method getMerchantOrderNo (line 43) | public String getMerchantOrderNo() {
    method getAmount (line 47) | public BigDecimal getAmount() {
    method getStatus (line 51) | public String getStatus() {
    method confirm (line 55) | public void confirm() {
    method cancel (line 59) | public void cancel() {
    method getVersion (line 63) | public long getVersion() {
    method updateVersion (line 67) | public void updateVersion() {

FILE: tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-redpacket/src/main/java/io/tyloo/sample/redpacket/domain/repository/RedPacketAccountRepository.java
  class RedPacketAccountRepository (line 11) | @Repository
    method findByUserId (line 17) | public RedPacketAccount findByUserId(long userId) {
    method save (line 22) | public void save(RedPacketAccount redPacketAccount) {

FILE: tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-redpacket/src/main/java/io/tyloo/sample/redpacket/domain/repository/TradeOrderRepository.java
  class TradeOrderRepository (line 10) | @Repository
    method insert (line 16) | public void insert(TradeOrder tradeOrder) {
    method update (line 20) | public void update(TradeOrder tradeOrder) {
    method findByMerchantOrderNo (line 29) | public TradeOrder findByMerchantOrderNo(String merchantOrderNo) {

FILE: tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-redpacket/src/main/java/io/tyloo/sample/redpacket/infrastructure/dao/RedPacketAccountDao.java
  type RedPacketAccountDao (line 6) | public interface RedPacketAccountDao {
    method findByUserId (line 8) | RedPacketAccount findByUserId(long userId);
    method update (line 10) | int update(RedPacketAccount redPacketAccount);

FILE: tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-redpacket/src/main/java/io/tyloo/sample/redpacket/infrastructure/dao/TradeOrderDao.java
  type TradeOrderDao (line 7) | public interface TradeOrderDao {
    method insert (line 9) | void insert(TradeOrder tradeOrder);
    method update (line 11) | int update(TradeOrder tradeOrder);
    method findByMerchantOrderNo (line 13) | TradeOrder findByMerchantOrderNo(String merchantOrderNo);

FILE: tyloo-unit-test/src/main/java/io/tyloo/unittest/client/AccountRecordServiceProxy.java
  class AccountRecordServiceProxy (line 15) | @Service
    method record (line 24) | public void record(final TransactionContext transactionContext, final ...
    method handleResult (line 40) | private void handleResult(Future<Boolean> future) {

FILE: tyloo-unit-test/src/main/java/io/tyloo/unittest/client/AccountServiceProxy.java
  class AccountServiceProxy (line 11) | @Service
    method transferFromWithMultipleTier (line 19) | public void transferFromWithMultipleTier(final TransactionContext tran...
    method transferToWithMultipleTier (line 32) | public void transferToWithMultipleTier(final TransactionContext transa...
    method performanceTuningTransferTo (line 46) | public void performanceTuningTransferTo(TransactionContext transaction...
    method transferTo (line 49) | public void transferTo(final TransactionContext transactionContext, fi...
    method transferTo (line 64) | public void transferTo(final long accountId, final int amount) {
    method transferFrom (line 80) | public void transferFrom(final TransactionContext transactionContext, ...
    method handleResult (line 97) | private void handleResult(Future<Boolean> future) {

FILE: tyloo-unit-test/src/main/java/io/tyloo/unittest/client/TransferService.java
  class TransferService (line 13) | @Service
    method TransferService (line 22) | public TransferService() {
    method performenceTuningTransfer (line 26) | @Tyloo
    method transferWithMandatoryPropagation (line 32) | @Tyloo(propagation = Propagation.MANDATORY)
    method transfer (line 45) | @Tyloo(confirmMethod = "transferConfirm", cancelMethod = "transferCanc...
    method transferWithMultipleTier (line 60) | @Tyloo(confirmMethod = "transferConfirm", cancelMethod = "transferCanc...
    method transferWithMultipleConsumer (line 74) | @Tyloo(confirmMethod = "transferWithMultipleConsumerConfirm", cancelMe...
    method transferWithOnlyTryAndMultipleConsumer (line 82) | @Tyloo
    method transferWithNoTransactionContext (line 89) | @Tyloo
    method transferConfirm (line 95) | public void transferConfirm(long fromAccountId, long toAccountId, int ...
    method transferCancel (line 101) | public void transferCancel(long fromAccountId, long toAccountId, int a...
    method transferWithMultipleConsumerConfirm (line 114) | public void transferWithMultipleConsumerConfirm(long fromAccountId, lo...
    method transferWithMultipleConsumerCancel (line 118) | public void transferWithMultipleConsumerCancel(long fromAccountId, lon...

FILE: tyloo-unit-test/src/main/java/io/tyloo/unittest/entity/AccountRecord.java
  class AccountRecord (line 4) | public class AccountRecord {
    method AccountRecord (line 12) | public AccountRecord(long accountId, int balanceAmount) {
    method getAccountId (line 17) | public long getAccountId() {
    method getBalanceAmount (line 21) | public int getBalanceAmount() {
    method setStatusId (line 25) | public void setStatusId(int statusId) {
    method setBalanceAmount (line 29) | public void setBalanceAmount(int balanceAmount) {
    method getStatusId (line 33) | public int getStatusId() {

FILE: tyloo-unit-test/src/main/java/io/tyloo/unittest/entity/AccountStatus.java
  type AccountStatus (line 4) | public enum AccountStatus {
    method AccountStatus (line 12) | AccountStatus(int id) {
    method getId (line 16) | public int getId() {

FILE: tyloo-unit-test/src/main/java/io/tyloo/unittest/entity/SubAccount.java
  class SubAccount (line 4) | public class SubAccount {
    method getId (line 12) | public long getId() {
    method setId (line 16) | public void setId(long id) {
    method getBalanceAmount (line 20) | public int getBalanceAmount() {
    method setBalanceAmount (line 24) | public void setBalanceAmount(int balanceAmount) {
    method SubAccount (line 28) | public SubAccount() {
    method SubAccount (line 32) | public SubAccount(long id, int balanceAmount) {
    method setStatus (line 37) | public void setStatus(int status) {
    method getStatus (line 41) | public int getStatus() {

FILE: tyloo-unit-test/src/main/java/io/tyloo/unittest/entity/UserShardingId.java
  class UserShardingId (line 7) | public abstract class UserShardingId implements Serializable {
    method UserShardingId (line 14) | public UserShardingId() {
    method UserShardingId (line 17) | public UserShardingId(Long userId) {
    method UserShardingId (line 21) | public UserShardingId(Long id, Long userId) {
    method getId (line 27) | public Long getId() {
    method setId (line 31) | public void setId(Long id) {
    method getUserId (line 35) | public Long getUserId() {
    method setUserId (line 39) | public void setUserId(Long userId) {
    method equals (line 43) | @Override
    method hashCode (line 75) | @Override

FILE: tyloo-unit-test/src/main/java/io/tyloo/unittest/repository/AccountRecordRepository.java
  class AccountRecordRepository (line 10) | @Repository
    method findById (line 21) | public AccountRecord findById(Long id) {

FILE: tyloo-unit-test/src/main/java/io/tyloo/unittest/repository/SubAccountRepository.java
  class SubAccountRepository (line 10) | @Repository
    method findById (line 21) | public SubAccount findById(Long id) {

FILE: tyloo-unit-test/src/main/java/io/tyloo/unittest/service/AccountService.java
  type AccountService (line 6) | public interface AccountService {
    method transferTo (line 8) | void transferTo(TransactionContext transactionContext, long accountId,...
    method transferToConfirm (line 10) | void transferToConfirm(TransactionContext transactionContext, long acc...
    method transferToCancel (line 12) | void transferToCancel(TransactionContext transactionContext, long acco...
    method transferToWithNoTransactionContext (line 14) | void transferToWithNoTransactionContext(long accountId, int amount);
    method transferToConfirmWithNoTransactionContext (line 16) | void transferToConfirmWithNoTransactionContext(long accountId, int amo...
    method transferToCancelWithNoTransactionContext (line 18) | void transferToCancelWithNoTransactionContext(long accountId, int amou...
    method transferFrom (line 20) | void transferFrom(TransactionContext transactionContext, long accountI...
    method transferFromConfirm (line 22) | void transferFromConfirm(TransactionContext transactionContext, long a...
    method transferFromCancel (line 24) | void transferFromCancel(TransactionContext transactionContext, long ac...
    method transferToWithMultipleTier (line 26) | void transferToWithMultipleTier(TransactionContext transactionContext,...
    method transferFromWithMultipleTier (line 28) | void transferFromWithMultipleTier(TransactionContext transactionContex...

FILE: tyloo-unit-test/src/main/java/io/tyloo/unittest/service/AccountServiceImpl.java
  class AccountServiceImpl (line 15) | @Service
    method transferFrom (line 25) | @Override
    method transferTo (line 35) | @Override
    method transferFromWithMultipleTier (line 45) | @Override
    method transferToWithMultipleTier (line 55) | @Override
    method transferToWithNoTransactionContext (line 69) | @Override
    method transferFromConfirm (line 81) | public void transferFromConfirm(TransactionContext transactionContext,...
    method transferFromCancel (line 87) | public void transferFromCancel(TransactionContext transactionContext, ...
    method transferToConfirm (line 98) | @Override
    method transferToCancel (line 110) | @Override
    method transferToConfirmWithNoTransactionContext (line 123) | public void transferToConfirmWithNoTransactionContext(long accountId, ...
    method transferToCancelWithNoTransactionContext (line 129) | public void transferToCancelWithNoTransactionContext(long accountId, i...

FILE: tyloo-unit-test/src/main/java/io/tyloo/unittest/thirdservice/AccountRecordService.java
  type AccountRecordService (line 6) | public interface AccountRecordService {
    method record (line 7) | public void record(TransactionContext transactionContext, long account...
    method recordConfirm (line 9) | void recordConfirm(TransactionContext transactionContext, long account...
    method recordCancel (line 11) | void recordCancel(TransactionContext transactionContext, long accountI...

FILE: tyloo-unit-test/src/main/java/io/tyloo/unittest/thirdservice/AccountRecordServiceImpl.java
  class AccountRecordServiceImpl (line 13) | @Service
    method record (line 19) | @Override
    method recordConfirm (line 34) | @Override
    method recordCancel (line 41) | @Override

FILE: tyloo-unit-test/src/main/java/io/tyloo/unittest/utils/UnitTest.java
  class UnitTest (line 4) | public class UnitTest {

FILE: tyloo-unit-test/src/test/java/io/tyloo/unit/test/AbstractTestCase.java
  class AbstractTestCase (line 8) | @RunWith(SpringJUnit4ClassRunner.class)

FILE: tyloo-unit-test/src/test/java/io/tyloo/unit/test/PerformanceTest.java
  class PerformanceTest (line 17) | public class PerformanceTest extends AbstractTestCase {
    method performanceTest (line 22) | @Test
    method serializeTest (line 36) | @Test
    method testThreadPool (line 59) | @Test

FILE: tyloo-unit-test/src/test/java/io/tyloo/unit/test/ReflectionTest.java
  class ReflectionTest (line 14) | public class ReflectionTest extends AbstractTestCase {
    method test1 (line 19) | @Test
    method testJacksonSerializer (line 29) | @Test

FILE: tyloo-unit-test/src/test/java/io/tyloo/unit/test/TransferServiceTest.java
  class TransferServiceTest (line 17) | public class TransferServiceTest extends AbstractTestCase {
    method testTransfer (line 31) | @Test
    method testTransferWithMandatoryPropagtion (line 52) | @Test
    method testTransferWithMultipleTier (line 66) | @Test
    method testTransferWithMultiplerConsumer (line 93) | @Test
    method testTransferWithOnlyTryAndMultipleConsumer (line 113) | @Test
    method testTransferWithNoTransactionContext (line 133) | @Test
    method testTryingRecovery (line 149) | @Test
    method testConfirmingRecovery (line 185) | @Test
    method buildAccount (line 234) | private void buildAccount() {
Condensed preview — 256 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (495K chars).
[
  {
    "path": ".gitignore",
    "chars": 232,
    "preview": "# maven ignore\ntarget/\n*.jar\n*.war\n*.zip\n*.tar\n*.tar.gz\n\n# eclipse ignore\n.settings/\n.project\n.classpath\n\n# idea ignore\n"
  },
  {
    "path": "README.md",
    "chars": 1671,
    "preview": "# tyloo\nDistributed transaction framework——TCC\n\n\n\n## 概念\n\n- Try: 尝试执行业务\n  - 完成所有业务检查(一致性)\n  - 预留必须业务资源(准隔离性)\n\n- Confirm: "
  },
  {
    "path": "pom.xml",
    "chars": 9422,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "tyloo-api/pom.xml",
    "chars": 694,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "tyloo-api/src/main/java/io/tyloo/api/Propagation.java",
    "chars": 491,
    "preview": "package io.tyloo.api;\n\n/*\n *\n * \n *\n * @Author:Zh1Cheung zh1cheunglq@gmail.com\n * @Date: 11:49 2019/4/4\n *\n */\n\npublic e"
  },
  {
    "path": "tyloo-api/src/main/java/io/tyloo/api/TransactionContext.java",
    "chars": 1255,
    "preview": "package io.tyloo.api;\n\nimport java.io.Serializable;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;"
  },
  {
    "path": "tyloo-api/src/main/java/io/tyloo/api/TransactionContextEditor.java",
    "chars": 652,
    "preview": "package io.tyloo.api;\n\nimport java.lang.reflect.Method;\n\n/*\n *\n * ı༭úͻ\n *\n * @Author:Zh1Cheung zh1cheunglq@gmail.com\n * "
  },
  {
    "path": "tyloo-api/src/main/java/io/tyloo/api/TransactionStatus.java",
    "chars": 686,
    "preview": "package io.tyloo.api;\n\n/*\n *\n * ״̬ö\n *\n * @Author:Zh1Cheung zh1cheunglq@gmail.com\n * @Date: 12:05 2019/4/5\n *\n */\npublic"
  },
  {
    "path": "tyloo-api/src/main/java/io/tyloo/api/TransactionXid.java",
    "chars": 4413,
    "preview": "package io.tyloo.api;\n\n\nimport javax.transaction.xa.Xid;\nimport java.io.Serializable;\nimport java.nio.ByteBuffer;\nimport"
  },
  {
    "path": "tyloo-api/src/main/java/io/tyloo/api/Tyloo.java",
    "chars": 2913,
    "preview": "package io.tyloo.api;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang."
  },
  {
    "path": "tyloo-api/src/main/java/io/tyloo/api/UniqueIdentity.java",
    "chars": 372,
    "preview": "package io.tyloo.api;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang."
  },
  {
    "path": "tyloo-api/src/main/java/io/tyloo/api/UuidUtils.java",
    "chars": 679,
    "preview": "package io.tyloo.api;\n\nimport java.nio.ByteBuffer;\n\nimport cn.hutool.core.lang.UUID;\n\n/*\n *\n * @Author:Zh1Cheung zh1cheu"
  },
  {
    "path": "tyloo-core/pom.xml",
    "chars": 1765,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/CancellingException.java",
    "chars": 242,
    "preview": "package io.tyloo;\n\n/*\n *\n * @Author:Zh1Cheung zh1cheunglq@gmail.com\n * @Date: 19:55 2019/6/1\n *\n */\npublic class Cancell"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/ConcurrentTransactionException.java",
    "chars": 496,
    "preview": "package io.tyloo;\n\n/*\n *\n * @Author:Zh1Cheung zh1cheunglq@gmail.com\n * @Date: 19:55 2019/6/1\n *\n */\npublic class Concurr"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/ConfirmingException.java",
    "chars": 241,
    "preview": "package io.tyloo;\n\n/*\n *\n * @Author:Zh1Cheung zh1cheunglq@gmail.com\n * @Date: 19:55 2019/6/1\n *\n */\npublic class Confirm"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/InvocationContext.java",
    "chars": 1107,
    "preview": "package io.tyloo;\n\nimport java.io.Serializable;\n\n/*\n *\n *  ִз\n *  ¼ࡢ顢顣\n *  ͨЩԣִύ / ع\n *\n * @Author:Zh1Cheung zh1cheunglq"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/NoExistedTransactionException.java",
    "chars": 236,
    "preview": "package io.tyloo;\n\n/*\n *\n * @Author:Zh1Cheung zh1cheunglq@gmail.com\n * @Date: 19:55 2019/6/1\n *\n */\npublic class NoExist"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/OptimisticLockException.java",
    "chars": 238,
    "preview": "package io.tyloo;\n\n/*\n *\n * @Author:Zh1Cheung zh1cheunglq@gmail.com\n * @Date: 19:55 2019/6/1\n *\n */\npublic class Optimis"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/Participant.java",
    "chars": 2252,
    "preview": "package io.tyloo;\n\nimport io.tyloo.api.TransactionContext;\nimport io.tyloo.api.TransactionContextEditor;\nimport io.tyloo"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/SystemException.java",
    "chars": 393,
    "preview": "package io.tyloo;\n\n/*\n *\n * @Author:Zh1Cheung zh1cheunglq@gmail.com\n * @Date: 19:55 2019/6/1\n *\n */\npublic class SystemE"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/Terminator.java",
    "chars": 1429,
    "preview": "package io.tyloo;\n\nimport io.tyloo.api.TransactionContext;\nimport io.tyloo.api.TransactionContextEditor;\nimport io.tyloo"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/Transaction.java",
    "chars": 3539,
    "preview": "package io.tyloo;\n\n\nimport io.tyloo.api.TransactionContext;\nimport io.tyloo.api.TransactionStatus;\nimport io.tyloo.api.T"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/TransactionManager.java",
    "chars": 6929,
    "preview": "package io.tyloo;\n\nimport io.tyloo.api.TransactionContext;\nimport io.tyloo.api.TransactionStatus;\nimport io.tyloo.common"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/TransactionRepository.java",
    "chars": 697,
    "preview": "package io.tyloo;\n\nimport io.tyloo.api.TransactionXid;\n\nimport java.util.Date;\nimport java.util.List;\n\n/*\n *\n * (tccݿdao"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/common/MethodRole.java",
    "chars": 251,
    "preview": "package io.tyloo.common;\n\n/*\n * ɫ\n *\n * @Author:Zh1Cheung zh1cheunglq@gmail.com\n * @Date: 15:27 2019/4/15\n *\n */\npublic "
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/common/TransactionType.java",
    "chars": 595,
    "preview": "package io.tyloo.common;\n\n/*\n * \n *\n * @Author:Zh1Cheung zh1cheunglq@gmail.com\n * @Date: 15:28 2019/4/17\n *\n */\n\npublic "
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/context/MethodTransactionContextEditor.java",
    "chars": 1011,
    "preview": "package io.tyloo.context;\n\nimport io.tyloo.api.TransactionContext;\nimport io.tyloo.api.TransactionContextEditor;\nimport "
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/interceptor/TylooCoordinatorAspect.java",
    "chars": 1011,
    "preview": "package io.tyloo.interceptor;\n\nimport org.aspectj.lang.ProceedingJoinPoint;\nimport org.aspectj.lang.annotation.Around;\ni"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/interceptor/TylooCoordinatorInterceptor.java",
    "chars": 3552,
    "preview": "package io.tyloo.interceptor;\n\nimport io.tyloo.InvocationContext;\nimport io.tyloo.Participant;\nimport io.tyloo.Transacti"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/interceptor/TylooMethodContext.java",
    "chars": 3324,
    "preview": "package io.tyloo.interceptor;\n\nimport io.tyloo.api.Propagation;\nimport io.tyloo.api.TransactionContext;\nimport io.tyloo."
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/interceptor/TylooTransactionAspect.java",
    "chars": 964,
    "preview": "package io.tyloo.interceptor;\n\nimport org.aspectj.lang.ProceedingJoinPoint;\nimport org.aspectj.lang.annotation.Around;\ni"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/interceptor/TylooTransactionInterceptor.java",
    "chars": 6488,
    "preview": "package io.tyloo.interceptor;\n\nimport com.alibaba.fastjson.JSON;\nimport io.tyloo.NoExistedTransactionException;\nimport i"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/recover/TylooRecoverConfiguration.java",
    "chars": 781,
    "preview": "package io.tyloo.recover;\n\nimport java.util.Set;\n\n/*\n * ָýӿ.\n *\n * @Author:Zh1Cheung zh1cheunglq@gmail.com\n * @Date: 18:"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/recover/TylooTransactionRecovery.java",
    "chars": 4833,
    "preview": "package io.tyloo.recover;\n\nimport com.alibaba.fastjson.JSON;\nimport io.tyloo.OptimisticLockException;\nimport io.tyloo.Tr"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/repository/CachableTransactionRepository.java",
    "chars": 4402,
    "preview": "package io.tyloo.repository;\n\n\nimport com.google.common.cache.Cache;\nimport com.google.common.cache.CacheBuilder;\nimport"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/repository/FileSystemTransactionRepository.java",
    "chars": 6845,
    "preview": "package io.tyloo.repository;\n\nimport io.tyloo.Transaction;\nimport io.tyloo.repository.helper.TransactionSerializer;\nimpo"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/repository/JdbcTransactionRepository.java",
    "chars": 11109,
    "preview": "package io.tyloo.repository;\n\n\nimport io.tyloo.Transaction;\nimport io.tyloo.api.TransactionStatus;\nimport io.tyloo.seria"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/repository/RedisTransactionRepository.java",
    "chars": 7721,
    "preview": "package io.tyloo.repository;\n\nimport io.tyloo.Transaction;\nimport io.tyloo.repository.helper.ExpandTransactionSerializer"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/repository/TransactionIOException.java",
    "chars": 416,
    "preview": "package io.tyloo.repository;\n\n/*\n *\n * IO쳣\n *\n * @Author:Zh1Cheung zh1cheunglq@gmail.com\n * @Date: 19:27 2019/5/16\n *\n *"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/repository/helper/ExpandTransactionSerializer.java",
    "chars": 2801,
    "preview": "package io.tyloo.repository.helper;\n\nimport com.alibaba.fastjson.JSON;\nimport io.tyloo.SystemException;\nimport io.tyloo."
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/repository/helper/JedisCallback.java",
    "chars": 366,
    "preview": "package io.tyloo.repository.helper;\n\nimport redis.clients.jedis.Jedis;\n\n/*\n * Jedisصӿ\n *\n * @Author:Zh1Cheung zh1cheungl"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/repository/helper/RedisHelper.java",
    "chars": 2854,
    "preview": "package io.tyloo.repository.helper;\n\nimport org.apache.log4j.Logger;\nimport redis.clients.jedis.Jedis;\nimport redis.clie"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/repository/helper/TransactionSerializer.java",
    "chars": 1707,
    "preview": "package io.tyloo.repository.helper;\n\nimport io.tyloo.Transaction;\nimport io.tyloo.serializer.ObjectSerializer;\n\nimport j"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/serializer/JacksonJsonSerializer.java",
    "chars": 1870,
    "preview": "package io.tyloo.serializer;\n\nimport com.fasterxml.jackson.annotation.JsonAutoDetect;\nimport com.fasterxml.jackson.annot"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/serializer/JdkSerializationSerializer.java",
    "chars": 750,
    "preview": "package io.tyloo.serializer;\n\nimport io.tyloo.Transaction;\nimport org.apache.commons.lang3.SerializationUtils;\n\n/*\n *\n *"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/serializer/KryoPoolSerializer.java",
    "chars": 2360,
    "preview": "package io.tyloo.serializer;\n\nimport com.esotericsoftware.kryo.Kryo;\nimport com.esotericsoftware.kryo.io.Input;\nimport c"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/serializer/ObjectSerializer.java",
    "chars": 566,
    "preview": "package io.tyloo.serializer;\n\n/*\n *\n * @Author:Zh1Cheung zh1cheunglq@gmail.com\n * @Date: 19:29 2019/5/22\n *\n */\npublic i"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/support/BeanFactory.java",
    "chars": 234,
    "preview": "package io.tyloo.support;\n\n/*\n *\n * Bean\n *\n * @Author:Zh1Cheung zh1cheunglq@gmail.com\n * @Date: 19:34 2019/5/27\n *\n */\n"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/support/FactoryBuilder.java",
    "chars": 3136,
    "preview": "package io.tyloo.support;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.ConcurrentHash"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/support/TransactionConfigurator.java",
    "chars": 601,
    "preview": "package io.tyloo.support;\n\nimport io.tyloo.TransactionManager;\nimport io.tyloo.TransactionRepository;\nimport io.tyloo.re"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/utils/ByteUtils.java",
    "chars": 552,
    "preview": "package io.tyloo.utils;\n\n/*\n *\n * @Author:Zh1Cheung zh1cheunglq@gmail.com\n * @Date: 19:49 2019/5/30\n *\n */\npublic class "
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/utils/CollectionUtils.java",
    "chars": 342,
    "preview": "package io.tyloo.utils;\n\nimport java.util.Collection;\n\n/*\n *\n * @Author:Zh1Cheung zh1cheunglq@gmail.com\n * @Date: 19:49 "
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/utils/ReflectionUtils.java",
    "chars": 2704,
    "preview": "package io.tyloo.utils;\n\nimport java.lang.annotation.Annotation;\nimport java.lang.reflect.Field;\nimport java.lang.reflec"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/utils/StringUtils.java",
    "chars": 351,
    "preview": "package io.tyloo.utils;\n\n/*\n *\n * @Author:Zh1Cheung zh1cheunglq@gmail.com\n * @Date: 19:49 2019/5/30\n *\n */\npublic class "
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/utils/TransactionUtils.java",
    "chars": 545,
    "preview": "package io.tyloo.utils;\n\nimport io.tyloo.api.Propagation;\nimport io.tyloo.interceptor.TylooMethodContext;\n\n/*\n *\n * @Aut"
  },
  {
    "path": "tyloo-core/src/main/java/io/tyloo/utils/TylooMethodUtils.java",
    "chars": 1850,
    "preview": "package io.tyloo.utils;\n\nimport io.tyloo.api.Propagation;\nimport io.tyloo.api.TransactionContext;\nimport io.tyloo.api.Ty"
  },
  {
    "path": "tyloo-dubbo/pom.xml",
    "chars": 1387,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "tyloo-dubbo/src/main/java/io/tyloo/dubbo/constants/TransactionContextConstants.java",
    "chars": 246,
    "preview": "package io.tyloo.dubbo.constants;\n\n/*\n *\n * ij\n *\n * @Author:Zh1Cheung zh1cheunglq@gmail.com\n * @Date: 9:33 2019/7/5\n *\n "
  },
  {
    "path": "tyloo-dubbo/src/main/java/io/tyloo/dubbo/context/DubboTransactionContextEditor.java",
    "chars": 1325,
    "preview": "package io.tyloo.dubbo.context;\n\nimport com.alibaba.fastjson.JSON;\nimport io.tyloo.api.TransactionContext;\nimport io.tyl"
  },
  {
    "path": "tyloo-dubbo/src/main/java/io/tyloo/dubbo/proxy/javassist/TylooClassGenerator.java",
    "chars": 13242,
    "preview": "package io.tyloo.dubbo.proxy.javassist;\n\nimport javassist.*;\nimport javassist.bytecode.AnnotationsAttribute;\nimport java"
  },
  {
    "path": "tyloo-dubbo/src/main/java/io/tyloo/dubbo/proxy/javassist/TylooJavassistProxyFactory.java",
    "chars": 814,
    "preview": "package io.tyloo.dubbo.proxy.javassist;\n\nimport org.apache.dubbo.rpc.Invoker;\nimport org.apache.dubbo.rpc.proxy.InvokerI"
  },
  {
    "path": "tyloo-dubbo/src/main/java/io/tyloo/dubbo/proxy/javassist/TylooProxy.java",
    "chars": 10541,
    "preview": "/*\n * Copyright 1999-2011 Alibaba Group.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "tyloo-dubbo/src/main/java/io/tyloo/dubbo/proxy/jdk/MethodProceedingJoinPoint.java",
    "chars": 8778,
    "preview": "package io.tyloo.dubbo.proxy.jdk;\n\nimport io.tyloo.SystemException;\nimport io.tyloo.utils.ReflectionUtils;\nimport org.as"
  },
  {
    "path": "tyloo-dubbo/src/main/java/io/tyloo/dubbo/proxy/jdk/TylooInvokerInvocationHandler.java",
    "chars": 2209,
    "preview": "package io.tyloo.dubbo.proxy.jdk;\n\nimport io.tyloo.api.Propagation;\nimport io.tyloo.api.Tyloo;\nimport io.tyloo.dubbo.con"
  },
  {
    "path": "tyloo-dubbo/src/main/java/io/tyloo/dubbo/proxy/jdk/TylooJdkProxyFactory.java",
    "chars": 1163,
    "preview": "package io.tyloo.dubbo.proxy.jdk;\n\nimport org.apache.dubbo.rpc.Invoker;\nimport org.apache.dubbo.rpc.proxy.InvokerInvocat"
  },
  {
    "path": "tyloo-dubbo/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.ProxyFactory",
    "chars": 71,
    "preview": "tylooJavassist=TylooJavassistProxyFactory\ntylooJdk=TylooJdkProxyFactory"
  },
  {
    "path": "tyloo-dubbo/src/main/resources/tyloo-dubbo.xml",
    "chars": 575,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http"
  },
  {
    "path": "tyloo-spring/pom.xml",
    "chars": 1963,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "tyloo-spring/src/main/dbscripts/db.sql",
    "chars": 711,
    "preview": "CREATE TABLE `TCC_TRANSACTION` (\n  `TRANSACTION_ID` int(11) NOT NULL AUTO_INCREMENT,\n  `DOMAIN` varchar(100) DEFAULT NUL"
  },
  {
    "path": "tyloo-spring/src/main/java/io/tyloo/spring/ConfigurableCoordinatorAspect.java",
    "chars": 1164,
    "preview": "package io.tyloo.spring;\n\nimport io.tyloo.interceptor.TylooCoordinatorAspect;\nimport io.tyloo.interceptor.TylooCoordinat"
  },
  {
    "path": "tyloo-spring/src/main/java/io/tyloo/spring/ConfigurableTransactionAspect.java",
    "chars": 1436,
    "preview": "package io.tyloo.spring;\n\nimport io.tyloo.TransactionManager;\nimport io.tyloo.interceptor.TylooTransactionAspect;\nimport"
  },
  {
    "path": "tyloo-spring/src/main/java/io/tyloo/spring/recover/DefaultTylooRecoverConfiguration.java",
    "chars": 2000,
    "preview": "package io.tyloo.spring.recover;\n\nimport io.tyloo.OptimisticLockException;\nimport io.tyloo.recover.TylooRecoverConfigura"
  },
  {
    "path": "tyloo-spring/src/main/java/io/tyloo/spring/recover/RecoverScheduledJob.java",
    "chars": 2721,
    "preview": "package io.tyloo.spring.recover;\n\nimport io.tyloo.SystemException;\nimport io.tyloo.recover.TylooTransactionRecovery;\nimp"
  },
  {
    "path": "tyloo-spring/src/main/java/io/tyloo/spring/repository/SpringJdbcTransactionRepository.java",
    "chars": 644,
    "preview": "package io.tyloo.spring.repository;\n\n\nimport io.tyloo.repository.JdbcTransactionRepository;\nimport org.springframework.j"
  },
  {
    "path": "tyloo-spring/src/main/java/io/tyloo/spring/support/SpringBeanFactory.java",
    "chars": 1043,
    "preview": "package io.tyloo.spring.support;\n\nimport io.tyloo.support.BeanFactory;\nimport io.tyloo.support.FactoryBuilder;\nimport or"
  },
  {
    "path": "tyloo-spring/src/main/java/io/tyloo/spring/support/SpringPostProcessor.java",
    "chars": 866,
    "preview": "package io.tyloo.spring.support;\n\nimport io.tyloo.support.BeanFactory;\nimport io.tyloo.support.FactoryBuilder;\nimport or"
  },
  {
    "path": "tyloo-spring/src/main/java/io/tyloo/spring/support/SpringTransactionConfigurator.java",
    "chars": 4072,
    "preview": "package io.tyloo.spring.support;\n\nimport io.tyloo.TransactionManager;\nimport io.tyloo.TransactionRepository;\nimport io.t"
  },
  {
    "path": "tyloo-spring/src/main/resources/tyloo.xml",
    "chars": 1994,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http"
  },
  {
    "path": "tyloo-tutorial-sample/pom.xml",
    "chars": 737,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "tyloo-tutorial-sample/src/tylooSampledb/create_db_cap.sql",
    "chars": 998,
    "preview": "CREATE DATABASE `TCC_CAP` /*!40100 DEFAULT CHARACTER SET utf8 */;\nuse TCC_CAP;\nCREATE TABLE `CAP_CAPITAL_ACCOUNT` (\n  `C"
  },
  {
    "path": "tyloo-tutorial-sample/src/tylooSampledb/create_db_ord.sql",
    "chars": 1707,
    "preview": "CREATE DATABASE `TCC_ORD` /*!40100 DEFAULT CHARACTER SET utf8 */;\nuse TCC_ORD;\nCREATE TABLE `ORD_ORDER` (\n  `ORDER_ID` i"
  },
  {
    "path": "tyloo-tutorial-sample/src/tylooSampledb/create_db_red.sql",
    "chars": 1017,
    "preview": "CREATE DATABASE `TCC_RED` /*!40100 DEFAULT CHARACTER SET utf8 */;\nuse TCC_RED;\nCREATE TABLE `RED_RED_PACKET_ACCOUNT` (\n "
  },
  {
    "path": "tyloo-tutorial-sample/src/tylooSampledb/create_db_tcc.sql",
    "chars": 2879,
    "preview": "CREATE DATABASE `TCC` /*!40100 DEFAULT CHARACTER SET utf8 */;\nuse TCC;\nCREATE TABLE `TCC_TRANSACTION_CAP` (\n  `TRANSACTI"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/pom.xml",
    "chars": 806,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/src/main/tylooSampledb/create_db_cap.sql",
    "chars": 911,
    "preview": "CREATE DATABASE `tcc_cap` /*!40100 DEFAULT CHARACTER SET utf8 */;\n\nuse tcc_cap;\n\nCREATE TABLE `CAP_CAPITAL_ACCOUNT` (\n  "
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/src/main/tylooSampledb/create_db_ord.sql",
    "chars": 1613,
    "preview": "CREATE DATABASE `TCC_ORD` /*!40100 DEFAULT CHARACTER SET utf8 */;\n\nuse TCC_ORD;\n\nCREATE TABLE `ORD_ORDER` (\n  `ORDER_ID`"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/src/main/tylooSampledb/create_db_red.sql",
    "chars": 924,
    "preview": "CREATE DATABASE `tcc_red` /*!40100 DEFAULT CHARACTER SET utf8 */;\nuse tcc_red;\nCREATE TABLE `RED_RED_PACKET_ACCOUNT` (\n "
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/src/main/tylooSampledb/create_db_tcc.sql",
    "chars": 2555,
    "preview": "CREATE DATABASE `TCC` /*!40100 DEFAULT CHARACTER SET utf8 */;\n\nuse TCC;\n\nCREATE TABLE `TCC_TRANSACTION_CAP` (\n  `TRANSAC"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-capital/pom.xml",
    "chars": 1928,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-capital/src/main/java/io/tyloo/sample/dubbo/capital/service/CapitalAccountServiceImpl.java",
    "chars": 675,
    "preview": "package io.tyloo.sample.dubbo.capital.service;\n\nimport io.tyloo.sample.capital.domain.repository.CapitalAccountRepositor"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-capital/src/main/java/io/tyloo/sample/dubbo/capital/service/CapitalTradeOrderServiceImpl.java",
    "chars": 4767,
    "preview": "package io.tyloo.sample.dubbo.capital.service;\n\nimport io.tyloo.sample.capital.domain.entity.CapitalAccount;\nimport io.t"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-capital/src/main/resources/config/spring/local/appcontext-service-provider.xml",
    "chars": 1491,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-capital/src/main/resources/config/spring/local/appcontext-service-tcc.xml",
    "chars": 3204,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-capital/src/main/resources/config/spring/local/appcontext-web-servlet.xml",
    "chars": 302,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-capital/src/main/resources/log/log4j.xml",
    "chars": 899,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE log4j:configuration PUBLIC \"-//log4j/log4j Configuration//EN\" \"log4j.dt"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-capital/src/main/resources/sample-dubbo-capital.properties",
    "chars": 111,
    "preview": "dubbo.port=2881\n\nzookeeper.address=127.0.0.1:2181\nzookeeper.session.timeout=8000\nzookeeper.connect.timeout=2000"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-capital/src/main/resources/tccjdbc.properties",
    "chars": 327,
    "preview": "jdbc.driverClassName=com.mysql.jdbc.Driver\ntcc.jdbc.url=jdbc:mysql://127.0.0.1:3306/TCC?useUnicode=true&characterEncodin"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-capital/src/main/webapp/WEB-INF/web.xml",
    "chars": 2188,
    "preview": "<!DOCTYPE web-app PUBLIC\n        \"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN\"\n        \"http://java.sun.com/d"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-capital/src/main/webapp/index.jsp",
    "chars": 41,
    "preview": "hello tcc transacton dubbo sample capital"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-capital-api/pom.xml",
    "chars": 683,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-capital-api/src/main/java/io/tyloo/sample/dubbo/capital/api/CapitalAccountService.java",
    "chars": 174,
    "preview": "package io.tyloo.sample.dubbo.capital.api;\n\nimport java.math.BigDecimal;\n\n\npublic interface CapitalAccountService {\n\n   "
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-capital-api/src/main/java/io/tyloo/sample/dubbo/capital/api/CapitalTradeOrderService.java",
    "chars": 261,
    "preview": "package io.tyloo.sample.dubbo.capital.api;\n\nimport io.tyloo.sample.dubbo.capital.api.dto.CapitalTradeOrderDto;\nimport io"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-capital-api/src/main/java/io/tyloo/sample/dubbo/capital/api/dto/CapitalTradeOrderDto.java",
    "chars": 1271,
    "preview": "package io.tyloo.sample.dubbo.capital.api.dto;\n\nimport java.io.Serializable;\nimport java.math.BigDecimal;\n\n\npublic class"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-order/pom.xml",
    "chars": 3620,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-order/src/main/java/io/tyloo/sample/dubbo/order/service/AccountServiceImpl.java",
    "chars": 806,
    "preview": "package io.tyloo.sample.dubbo.order.service;\n\nimport io.tyloo.sample.dubbo.capital.api.CapitalAccountService;\nimport io."
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-order/src/main/java/io/tyloo/sample/dubbo/order/service/PaymentServiceImpl.java",
    "chars": 5024,
    "preview": "package io.tyloo.sample.dubbo.order.service;\n\nimport io.tyloo.sample.dubbo.capital.api.CapitalTradeOrderService;\nimport "
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-order/src/main/java/io/tyloo/sample/dubbo/order/service/PlaceOrderServiceImpl.java",
    "chars": 2811,
    "preview": "package io.tyloo.sample.dubbo.order.service;\n\nimport io.tyloo.sample.order.domain.entity.Order;\nimport io.tyloo.sample.o"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-order/src/main/java/io/tyloo/sample/dubbo/order/web/controller/OrderController.java",
    "chars": 4972,
    "preview": "package io.tyloo.sample.dubbo.order.web.controller;\n\nimport io.tyloo.sample.dubbo.order.service.AccountServiceImpl;\nimpo"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-order/src/main/java/io/tyloo/sample/dubbo/order/web/controller/vo/PlaceOrderRequest.java",
    "chars": 1190,
    "preview": "package io.tyloo.sample.dubbo.order.web.controller.vo;\n\nimport org.apache.commons.lang3.tuple.Pair;\n\nimport java.math.Bi"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-order/src/main/resources/config/spring/local/appcontext-service-dubbo.xml",
    "chars": 1683,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-order/src/main/resources/config/spring/local/appcontext-service-tcc.xml",
    "chars": 3733,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-order/src/main/resources/config/spring/local/appcontext-web-servlet.xml",
    "chars": 5240,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-order/src/main/resources/log/log4j.xml",
    "chars": 897,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE log4j:configuration PUBLIC \"-//log4j/log4j Configuration//EN\" \"log4j.dt"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-order/src/main/resources/sample-dubbo-order.properties",
    "chars": 96,
    "preview": "\n\nzookeeper.address=127.0.0.1:2181\nzookeeper.session.timeout=8000\nzookeeper.connect.timeout=2000"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-order/src/main/resources/tccjdbc.properties",
    "chars": 326,
    "preview": "jdbc.driverClassName=com.mysql.jdbc.Driver\ntcc.jdbc.url=jdbc:mysql://127.0.0.1:3306/TCC?useUnicode=true&characterEncodin"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-order/src/main/webapp/WEB-INF/ftl/index.ftl",
    "chars": 992,
    "preview": "[#ftl ]\n\n<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>tcc transacton dubbo sample or"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-order/src/main/webapp/WEB-INF/ftl/pay_success.ftl",
    "chars": 308,
    "preview": "[#ftl ]\n\n<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>支付结果</title>\n</head>\n<body>\n<d"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-order/src/main/webapp/WEB-INF/ftl/product_detail.ftl",
    "chars": 798,
    "preview": "[#ftl ]\n\n<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>订单详情</title>\n</head>\n<body>\n<d"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-order/src/main/webapp/WEB-INF/ftl/shop.ftl",
    "chars": 607,
    "preview": "[#ftl ]\n\n<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>商品列表</title>\n</head>\n<body>\n<d"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-order/src/main/webapp/WEB-INF/web.xml",
    "chars": 2187,
    "preview": "<!DOCTYPE web-app PUBLIC\n        \"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN\"\n        \"http://java.sun.com/d"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-redpacket/pom.xml",
    "chars": 3280,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-redpacket/src/main/java/io/tyloo/sample/dubbo/redpacket/service/RedPacketAccountServiceImpl.java",
    "chars": 699,
    "preview": "package io.tyloo.sample.dubbo.redpacket.service;\n\nimport io.tyloo.sample.dubbo.redpacket.api.RedPacketAccountService;\nim"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-redpacket/src/main/java/io/tyloo/sample/dubbo/redpacket/service/RedPacketTradeOrderServiceImpl.java",
    "chars": 4833,
    "preview": "package io.tyloo.sample.dubbo.redpacket.service;\n\nimport io.tyloo.sample.dubbo.redpacket.api.RedPacketTradeOrderService;"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-redpacket/src/main/resources/config/spring/local/appcontext-service-provider.xml",
    "chars": 1604,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-redpacket/src/main/resources/config/spring/local/appcontext-service-tcc.xml",
    "chars": 3207,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-redpacket/src/main/resources/config/spring/local/appcontext-web-servlet.xml",
    "chars": 309,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-redpacket/src/main/resources/log/log4j.xml",
    "chars": 901,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE log4j:configuration PUBLIC \"-//log4j/log4j Configuration//EN\" \"log4j.dt"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-redpacket/src/main/resources/sample-dubbo-redpacket.properties",
    "chars": 112,
    "preview": "dubbo.port=2880\n\nzookeeper.address=127.0.0.1:2181\nzookeeper.session.timeout=30000\nzookeeper.connect.timeout=2000"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-redpacket/src/main/resources/tccjdbc.properties",
    "chars": 327,
    "preview": "jdbc.driverClassName=com.mysql.jdbc.Driver\ntcc.jdbc.url=jdbc:mysql://127.0.0.1:3306/TCC?useUnicode=true&characterEncodin"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-redpacket/src/main/webapp/WEB-INF/web.xml",
    "chars": 2190,
    "preview": "<!DOCTYPE web-app PUBLIC\n        \"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN\"\n        \"http://java.sun.com/d"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-redpacket/src/main/webapp/index.jsp",
    "chars": 44,
    "preview": "hello tcc transacton dubbo sample red packet"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-redpacket-api/pom.xml",
    "chars": 685,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-redpacket-api/src/main/java/io/tyloo/sample/dubbo/redpacket/api/RedPacketAccountService.java",
    "chars": 179,
    "preview": "package io.tyloo.sample.dubbo.redpacket.api;\n\nimport java.math.BigDecimal;\n\n\npublic interface RedPacketAccountService {\n"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-redpacket-api/src/main/java/io/tyloo/sample/dubbo/redpacket/api/RedPacketTradeOrderService.java",
    "chars": 270,
    "preview": "package io.tyloo.sample.dubbo.redpacket.api;\n\nimport io.tyloo.sample.dubbo.redpacket.api.dto.RedPacketTradeOrderDto;\nimp"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-dubbo-sample/tyloo-dubbo-redpacket-api/src/main/java/io/tyloo/sample/dubbo/redpacket/api/dto/RedPacketTradeOrderDto.java",
    "chars": 1271,
    "preview": "package io.tyloo.sample.dubbo.redpacket.api.dto;\n\nimport java.io.Serializable;\nimport java.math.BigDecimal;\n\n\npublic cla"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/pom.xml",
    "chars": 800,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-capital/pom.xml",
    "chars": 1580,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-capital/src/main/java/io/tyloo/sample/http/capital/service/CapitalAccountServiceImpl.java",
    "chars": 593,
    "preview": "package io.tyloo.sample.http.capital.service;\n\nimport io.tyloo.sample.capital.domain.repository.CapitalAccountRepository"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-capital/src/main/java/io/tyloo/sample/http/capital/service/CapitalTradeOrderServiceImpl.java",
    "chars": 4833,
    "preview": "package io.tyloo.sample.http.capital.service;\n\nimport io.tyloo.sample.capital.domain.entity.CapitalAccount;\nimport io.ty"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-capital/src/main/resources/config/spring/local/appcontext-service-provider.xml",
    "chars": 1890,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-capital/src/main/resources/config/spring/local/appcontext-service-tcc.xml",
    "chars": 3259,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-capital/src/main/resources/config/spring/local/appcontext-web-servlet.xml",
    "chars": 546,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-capital/src/main/resources/log/log4j.xml",
    "chars": 898,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE log4j:configuration PUBLIC \"-//log4j/log4j Configuration//EN\" \"log4j.dt"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-capital/src/main/resources/tccjdbc.properties",
    "chars": 435,
    "preview": "jdbc.driverClassName=com.mysql.jdbc.Driver\njdbc.url=jdbc:mysql://127.0.0.1:3306/TCC_CAP?useUnicode=true&characterEncodin"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-capital/src/main/webapp/WEB-INF/web.xml",
    "chars": 2291,
    "preview": "<!DOCTYPE web-app PUBLIC\n        \"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN\"\n        \"http://java.sun.com/d"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-capital/src/main/webapp/index.jsp",
    "chars": 40,
    "preview": "hello tcc transacton http sample capital"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-capital-api/pom.xml",
    "chars": 681,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-capital-api/src/main/java/io/tyloo/sample/http/capital/api/CapitalAccountService.java",
    "chars": 172,
    "preview": "package io.tyloo.sample.http.capital.api;\n\nimport java.math.BigDecimal;\n\npublic interface CapitalAccountService {\n\n    B"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-capital-api/src/main/java/io/tyloo/sample/http/capital/api/CapitalTradeOrderService.java",
    "chars": 298,
    "preview": "package io.tyloo.sample.http.capital.api;\n\nimport io.tyloo.sample.http.capital.api.dto.CapitalTradeOrderDto;\nimport io.t"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-capital-api/src/main/java/io/tyloo/sample/http/capital/api/dto/CapitalTradeOrderDto.java",
    "chars": 1270,
    "preview": "package io.tyloo.sample.http.capital.api.dto;\n\nimport java.io.Serializable;\nimport java.math.BigDecimal;\n\n\npublic class "
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-order/pom.xml",
    "chars": 3713,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-order/src/main/java/io/tyloo/sample/http/order/service/AccountServiceImpl.java",
    "chars": 803,
    "preview": "package io.tyloo.sample.http.order.service;\n\nimport io.tyloo.sample.http.capital.api.CapitalAccountService;\nimport io.ty"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-order/src/main/java/io/tyloo/sample/http/order/service/PaymentServiceImpl.java",
    "chars": 4430,
    "preview": "package io.tyloo.sample.http.order.service;\n\nimport io.tyloo.sample.http.capital.api.dto.CapitalTradeOrderDto;\nimport io"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-order/src/main/java/io/tyloo/sample/http/order/service/PlaceOrderServiceImpl.java",
    "chars": 2117,
    "preview": "package io.tyloo.sample.http.order.service;\n\nimport io.tyloo.sample.order.domain.entity.Order;\nimport io.tyloo.sample.or"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-order/src/main/java/io/tyloo/sample/http/order/service/TradeOrderServiceProxy.java",
    "chars": 1695,
    "preview": "package io.tyloo.sample.http.order.service;\n\nimport io.tyloo.sample.http.capital.api.CapitalTradeOrderService;\nimport io"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-order/src/main/java/io/tyloo/sample/http/order/web/controller/OrderController.java",
    "chars": 4968,
    "preview": "package io.tyloo.sample.http.order.web.controller;\n\nimport io.tyloo.sample.http.order.service.AccountServiceImpl;\nimport"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-order/src/main/java/io/tyloo/sample/http/order/web/controller/vo/PlaceOrderRequest.java",
    "chars": 1189,
    "preview": "package io.tyloo.sample.http.order.web.controller.vo;\n\nimport org.apache.commons.lang3.tuple.Pair;\n\nimport java.math.Big"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-order/src/main/resources/config/spring/local/appcontext-service-consumer.xml",
    "chars": 2355,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-order/src/main/resources/config/spring/local/appcontext-service-tcc.xml",
    "chars": 3608,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-order/src/main/resources/config/spring/local/appcontext-web-servlet.xml",
    "chars": 5333,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-order/src/main/resources/log/log4j.xml",
    "chars": 896,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE log4j:configuration PUBLIC \"-//log4j/log4j Configuration//EN\" \"log4j.dt"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-order/src/main/resources/sample-dubbo-order.properties",
    "chars": 100,
    "preview": "\n\nzookeeper.address=127.0.0.1:2181\nzookeeper.session.timeout=1800000\nzookeeper.connect.timeout=30000"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-order/src/main/resources/tccjdbc.properties",
    "chars": 436,
    "preview": "jdbc.driverClassName=com.mysql.jdbc.Driver\njdbc.url=jdbc:mysql://127.0.0.1:3306/TCC_ORD?useUnicode=true&characterEncodin"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-order/src/main/webapp/WEB-INF/ftl/index.ftl",
    "chars": 1014,
    "preview": "[#ftl ]\n\n<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>tcc transacton dubbo sample or"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-order/src/main/webapp/WEB-INF/ftl/pay_success.ftl",
    "chars": 307,
    "preview": "[#ftl ]\n\n<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>支付结果</title>\n</head>\n<body>\n<d"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-order/src/main/webapp/WEB-INF/ftl/product_detail.ftl",
    "chars": 820,
    "preview": "[#ftl ]\n\n<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>订单详情</title>\n</head>\n<body>\n<d"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-order/src/main/webapp/WEB-INF/ftl/shop.ftl",
    "chars": 629,
    "preview": "[#ftl ]\n\n<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>商品列表</title>\n</head>\n<body>\n<d"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-order/src/main/webapp/WEB-INF/web.xml",
    "chars": 2308,
    "preview": "<!DOCTYPE web-app PUBLIC\n        \"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN\"\n        \"http://java.sun.com/d"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-redpacket/pom.xml",
    "chars": 3095,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-redpacket/src/main/java/io/tyloo/sample/http/redpacket/service/RedPacketAccountServiceImpl.java",
    "chars": 614,
    "preview": "package io.tyloo.sample.http.redpacket.service;\n\nimport io.tyloo.sample.http.redpacket.api.RedPacketAccountService;\nimpo"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-redpacket/src/main/java/io/tyloo/sample/http/redpacket/service/RedPacketTradeOrderServiceImpl.java",
    "chars": 4617,
    "preview": "package io.tyloo.sample.http.redpacket.service;\n\nimport io.tyloo.sample.http.redpacket.api.RedPacketTradeOrderService;\ni"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-redpacket/src/main/resources/config/spring/local/appcontext-service-provider.xml",
    "chars": 1926,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-redpacket/src/main/resources/config/spring/local/appcontext-service-tcc.xml",
    "chars": 3266,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-redpacket/src/main/resources/config/spring/local/appcontext-web-servlet.xml",
    "chars": 309,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-redpacket/src/main/resources/log/log4j.xml",
    "chars": 900,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE log4j:configuration PUBLIC \"-//log4j/log4j Configuration//EN\" \"log4j.dt"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-redpacket/src/main/resources/tccjdbc.properties",
    "chars": 435,
    "preview": "jdbc.driverClassName=com.mysql.jdbc.Driver\njdbc.url=jdbc:mysql://127.0.0.1:3306/TCC_RED?useUnicode=true&characterEncodin"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-redpacket/src/main/webapp/WEB-INF/web.xml",
    "chars": 2326,
    "preview": "<!DOCTYPE web-app PUBLIC\n        \"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN\"\n        \"http://java.sun.com/d"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-redpacket/src/main/webapp/index.jsp",
    "chars": 43,
    "preview": "hello tcc transacton http sample red packet"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-redpacket-api/pom.xml",
    "chars": 683,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-redpacket-api/src/main/java/io/tyloo/sample/http/redpacket/api/RedPacketAccountService.java",
    "chars": 178,
    "preview": "package io.tyloo.sample.http.redpacket.api;\n\nimport java.math.BigDecimal;\n\n\npublic interface RedPacketAccountService {\n "
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-redpacket-api/src/main/java/io/tyloo/sample/http/redpacket/api/RedPacketTradeOrderService.java",
    "chars": 309,
    "preview": "package io.tyloo.sample.http.redpacket.api;\n\nimport io.tyloo.sample.http.redpacket.api.dto.RedPacketTradeOrderDto;\nimpor"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-http-sample/tyloo-http-redpacket-api/src/main/java/io/tyloo/sample/http/redpacket/api/dto/RedPacketTradeOrderDto.java",
    "chars": 1270,
    "preview": "package io.tyloo.sample.http.redpacket.api.dto;\n\nimport java.io.Serializable;\nimport java.math.BigDecimal;\n\n\npublic clas"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-sample-domain/pom.xml",
    "chars": 757,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-captial/pom.xml",
    "chars": 2257,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-captial/src/main/java/io/tyloo/sample/capital/domain/entity/CapitalAccount.java",
    "chars": 1150,
    "preview": "package io.tyloo.sample.capital.domain.entity;\n\n\n\nimport io.tyloo.sample.exception.InsufficientBalanceException;\n\nimport"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-captial/src/main/java/io/tyloo/sample/capital/domain/entity/TradeOrder.java",
    "chars": 1315,
    "preview": "package io.tyloo.sample.capital.domain.entity;\n\nimport java.math.BigDecimal;\n\npublic class TradeOrder {\n\n    private lon"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-captial/src/main/java/io/tyloo/sample/capital/domain/repository/CapitalAccountRepository.java",
    "chars": 812,
    "preview": "package io.tyloo.sample.capital.domain.repository;\n\nimport io.tyloo.sample.capital.domain.entity.CapitalAccount;\nimport "
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-captial/src/main/java/io/tyloo/sample/capital/domain/repository/TradeOrderRepository.java",
    "chars": 976,
    "preview": "package io.tyloo.sample.capital.domain.repository;\n\nimport io.tyloo.sample.capital.domain.entity.TradeOrder;\nimport io.t"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-captial/src/main/java/io/tyloo/sample/capital/infrastructure/dao/CapitalAccountDao.java",
    "chars": 250,
    "preview": "package io.tyloo.sample.capital.infrastructure.dao;\n\nimport io.tyloo.sample.capital.domain.entity.CapitalAccount;\n\n\npubl"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-captial/src/main/java/io/tyloo/sample/capital/infrastructure/dao/TradeOrderDao.java",
    "chars": 291,
    "preview": "package io.tyloo.sample.capital.infrastructure.dao;\n\n\nimport io.tyloo.sample.capital.domain.entity.TradeOrder;\n\n\npublic "
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-captial/src/main/resources/config/spring/local/appcontext-service-dao.xml",
    "chars": 1622,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-captial/src/main/resources/config/spring/local/appcontext-service-datasource.xml",
    "chars": 1873,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-captial/src/main/resources/config/sqlmap/main/sample-capitalaccount.xml",
    "chars": 1576,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-captial/src/main/resources/config/sqlmap/main/sample-tradeorder.xml",
    "chars": 1943,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-captial/src/main/resources/jdbc.properties",
    "chars": 435,
    "preview": "jdbc.driverClassName=com.mysql.jdbc.Driver\njdbc.url=jdbc:mysql://127.0.0.1:3306/TCC_CAP?useUnicode=true&characterEncodin"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-captial/src/main/resources/log/log4j.xml",
    "chars": 893,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE log4j:configuration PUBLIC \"-//log4j/log4j Configuration//EN\" \"log4j.dt"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-common/pom.xml",
    "chars": 543,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-common/src/main/java/io/tyloo/sample/exception/InsufficientBalanceException.java",
    "chars": 320,
    "preview": "package io.tyloo.sample.exception;\n\n\npublic class InsufficientBalanceException extends RuntimeException {\n    private st"
  },
  {
    "path": "tyloo-tutorial-sample/tyloo-sample-domain/tyloo-sample-order/pom.xml",
    "chars": 2462,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www"
  }
]

// ... and 56 more files (download for full content)

About this extraction

This page contains the full source code of the Zh1Cheung/tyloo GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 256 files (431.2 KB), approximately 116.0k tokens, and a symbol index with 844 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!