Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changes/en-us/develop.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Add changes here for all PR submitted to the develop branch.
- [[#5472](https://github.com/seata/seata/pull/5472)] fix if using `@GlobalTransactional` in RM, `ShouldNeverHappenException` will be thrown
- [[#5535](https://github.com/seata/seata/pull/5535)] fix the log file path was loaded incorrectly
- [[#5538](https://github.com/seata/seata/pull/5538)] fix finished transaction swallows exception when committing
- [[#5539](https://github.com/seata/seata/pull/5539)] fix the full table scan issue with 'setDate' condition in Oracle 10g

### optimize:
- [[#5208](https://github.com/seata/seata/pull/5208)] optimize throwable getCause once more
Expand Down
1 change: 1 addition & 0 deletions changes/zh-cn/develop.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
- [[#5472](https://github.com/seata/seata/pull/5472)] 在RM中使用`@GlobalTransactional`时,如果RM执行失败会抛出`ShouldNeverHappenException`
- [[#5535](https://github.com/seata/seata/pull/5535)] 修复读取logback文件路径错误的问题
- [[#5538](https://github.com/seata/seata/pull/5538)] 修复提交事务时事务已完成不抛出异常问题
- [[#5539](https://github.com/seata/seata/pull/5539)] 修复Oracle 10g where条件包含setDate全表扫描问题

### optimize:
- [[#5208](https://github.com/seata/seata/pull/5208)] 优化多次重复获取Throwable#getCause问题
Expand Down
82 changes: 82 additions & 0 deletions common/src/main/java/io/seata/common/util/DateUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright 1999-2019 Seata.io 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.seata.common.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
* The type Date util.
*
* @author slievrly
*/
public class DateUtil {

/**
* Gets current date.
*
* @return the current date
*/
public static Date getCurrentDate() {
return new Date();
}

/**
* Parse date date.
*
* @param dateStr the date str
* @param format the format
* @return the date
* @throws ParseException the parse exception
*/
public static Date parseDate(String dateStr, String format) throws ParseException {
if (StringUtils.isBlank(dateStr)) {
return null;
}
SimpleDateFormat sdf = new SimpleDateFormat(format);
return sdf.parse(dateStr);
}

public static Date parseDateWithoutTime(String dateStr) throws ParseException {
return parseDate(dateStr, "yyyy-MM-dd");
}

public static Date getDateNowPlusDays(int days) throws ParseException {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, days);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
String dateStr = dateFormat.format(calendar.getTime());
return dateFormat.parse(dateStr);
}

/**
* Format date string.
*
* @param date the date
* @param format the format
* @return the string
*/
public static String formatDate(Date date, String format) {
if (date == null) {
return null;
}
SimpleDateFormat sdf = new SimpleDateFormat(format);
return sdf.format(date);
}
}
57 changes: 57 additions & 0 deletions common/src/test/java/io/seata/common/util/DateUtilTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright 1999-2019 Seata.io 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.seata.common.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

/**
* @author slievrly
*/
public class DateUtilTest {
@Test
public void testGetCurrentDate() {
Date currentDate = DateUtil.getCurrentDate();
Assertions.assertNotNull(currentDate);
}

@Test
public void testParseDate() throws ParseException {
String dateStr = "2021-01-01";
Date date = DateUtil.parseDate(dateStr, "yyyy-MM-dd");
Assertions.assertNotNull(date);

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Assertions.assertEquals(dateStr, sdf.format(date));
}

@Test
public void testFormatDate() {
Date currentDate = DateUtil.getCurrentDate();
String dateStr = DateUtil.formatDate(currentDate, "yyyy-MM-dd HH:mm:ss");
Assertions.assertNotNull(dateStr);
}

@Test
public void testGetDateNowPlusDays() throws ParseException {
Assertions.assertNotNull(DateUtil.getDateNowPlusDays(2));
}
}
17 changes: 10 additions & 7 deletions rm-datasource/src/main/java/io/seata/rm/RMHandlerAT.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Calendar;
import java.text.ParseException;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import io.seata.common.util.DateUtil;
import io.seata.core.model.BranchType;
import io.seata.core.model.ResourceManager;
import io.seata.core.protocol.transaction.UndoLogDeleteRequest;
Expand Down Expand Up @@ -126,13 +127,15 @@ int deleteUndoLog(UndoLogManager manager, Connection conn, Date division) {
}
}

private Date getLogCreated(int saveDays) {
if (saveDays <= 0) {
saveDays = UndoLogDeleteRequest.DEFAULT_SAVE_DAYS;
private Date getLogCreated(int pastDays) {
if (pastDays <= 0) {
pastDays = UndoLogDeleteRequest.DEFAULT_SAVE_DAYS;
}
try {
return DateUtil.getDateNowPlusDays(-pastDays);
} catch (ParseException exx) {
throw new RuntimeException(exx);
}
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, -saveDays);
return calendar.getTime();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
*/
package io.seata.rm.datasource.undo.oracle;


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Date;

import io.seata.common.loader.LoadLevel;
import io.seata.common.util.DateUtil;
import io.seata.core.compressor.CompressorType;
import io.seata.core.constants.ClientTableColumnsName;
import io.seata.rm.datasource.undo.AbstractUndoLogManager;
Expand All @@ -47,13 +47,13 @@ public class OracleUndoLogManager extends AbstractUndoLogManager {
+ ClientTableColumnsName.UNDO_LOG_LOG_CREATED + ", " + ClientTableColumnsName.UNDO_LOG_LOG_MODIFIED + ")"
+ "VALUES (UNDO_LOG_SEQ.nextval, ?, ?, ?, ?, ?, sysdate, sysdate)";

private static final String DELETE_UNDO_LOG_BY_CREATE_SQL = "DELETE FROM " + UNDO_LOG_TABLE_NAME +
" WHERE " + ClientTableColumnsName.UNDO_LOG_LOG_CREATED + " <= ? and ROWNUM <= ?";
private static final String DELETE_UNDO_LOG_BY_CREATE_SQL = "DELETE FROM " + UNDO_LOG_TABLE_NAME + " WHERE " + ClientTableColumnsName.UNDO_LOG_LOG_CREATED + " <= to_date(?,'yyyy-mm-dd hh24:mi:ss') and ROWNUM <= ?";

@Override
public int deleteUndoLogByLogCreated(Date logCreated, int limitRows, Connection conn) throws SQLException {
try (PreparedStatement deletePST = conn.prepareStatement(DELETE_UNDO_LOG_BY_CREATE_SQL)) {
deletePST.setDate(1, new java.sql.Date(logCreated.getTime()));
String dateStr = DateUtil.formatDate(logCreated, "yyyy-MM-dd HH:mm:ss");
deletePST.setString(1, dateStr);
deletePST.setInt(2, limitRows);
int deleteRows = deletePST.executeUpdate();
if (LOGGER.isDebugEnabled()) {
Expand Down
5 changes: 2 additions & 3 deletions script/client/at/db/mysql.sql
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,5 @@ CREATE TABLE IF NOT EXISTS `undo_log`
`log_created` DATETIME(6) NOT NULL COMMENT 'create datetime',
`log_modified` DATETIME(6) NOT NULL COMMENT 'modify datetime',
UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB
AUTO_INCREMENT = 1
DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table';
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table';
ALTER TABLE `undo_log` ADD INDEX `ix_log_created` (`log_created`);
14 changes: 8 additions & 6 deletions script/client/at/db/oracle.sql
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
-- for AT mode you must to init this sql for you business database. the seata server not need it.
CREATE TABLE undo_log
(
id NUMBER(19) NOT NULL,
branch_id NUMBER(19) NOT NULL,
xid VARCHAR2(128) NOT NULL,
context VARCHAR2(128) NOT NULL,
rollback_info BLOB NOT NULL,
log_status NUMBER(10) NOT NULL,
log_created TIMESTAMP(0) NOT NULL,
log_modified TIMESTAMP(0) NOT NULL,
PRIMARY KEY (id),
CONSTRAINT ux_undo_log UNIQUE (xid, branch_id)
);

CREATE INDEX ix_log_created ON undo_log(log_created);
COMMENT ON TABLE undo_log IS 'AT transaction mode undo table';

-- Generate ID using sequence and trigger
CREATE SEQUENCE UNDO_LOG_SEQ START WITH 1 INCREMENT BY 1;
COMMENT ON COLUMN undo_log.branch_id is 'branch transaction id';
COMMENT ON COLUMN undo_log.xid is 'global transaction id';
COMMENT ON COLUMN undo_log.context is 'undo_log context,such as serialization';
COMMENT ON COLUMN undo_log.rollback_info is 'rollback info';
COMMENT ON COLUMN undo_log.log_status is '0:normal status,1:defense status';
COMMENT ON COLUMN undo_log.log_created is 'create datetime';
COMMENT ON COLUMN undo_log.log_modified is 'modify datetime';
12 changes: 9 additions & 3 deletions script/client/at/db/postgresql.sql
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
-- for AT mode you must to init this sql for you business database. the seata server not need it.
CREATE TABLE IF NOT EXISTS public.undo_log
(
id SERIAL NOT NULL,
branch_id BIGINT NOT NULL,
xid VARCHAR(128) NOT NULL,
context VARCHAR(128) NOT NULL,
rollback_info BYTEA NOT NULL,
log_status INT NOT NULL,
log_created TIMESTAMP(0) NOT NULL,
log_modified TIMESTAMP(0) NOT NULL,
CONSTRAINT pk_undo_log PRIMARY KEY (id),
CONSTRAINT ux_undo_log UNIQUE (xid, branch_id)
);
CREATE INDEX ix_log_created ON undo_log(log_created);

CREATE SEQUENCE IF NOT EXISTS undo_log_id_seq INCREMENT BY 1 MINVALUE 1 ;
COMMENT ON TABLE public.undo_log IS 'AT transaction mode undo table';
COMMENT ON COLUMN public.undo_log.branch_id IS 'branch transaction id';
COMMENT ON COLUMN public.undo_log.xid IS 'global transaction id';
COMMENT ON COLUMN public.undo_log.context IS 'undo_log context,such as serialization';
COMMENT ON COLUMN public.undo_log.rollback_info IS 'rollback info';
COMMENT ON COLUMN public.undo_log.log_status IS '0:normal status,1:defense status';
COMMENT ON COLUMN public.undo_log.log_created IS 'create datetime';
COMMENT ON COLUMN public.undo_log.log_modified IS 'modify datetime';