Oracle中的PostgreSQL XMIN& MySQL的

时间:2017-05-09 04:21:29

标签: java mysql sql oracle postgresql

我正在尝试在Oracle和&amp ;;上获得此代码的等价物。 MySQL的

if(vardbtype.equals("POSTGRESQL")){
            Long previousTxId = 0L;
            Long nextTxId = 0L;

            Class.forName("org.postgresql.Driver");
            System.out.println("----------------------------");

            try(Connection c = DriverManager.getConnection("jdbc:postgresql://localhost:5432/"+ vardbserver, vardbuser, vardbpassword);
                 PreparedStatement stmts = c.prepareStatement("SELECT * FROM "+ vardbname +" where xmin::varchar::bigint > ? and xmin::varchar::bigint < ? ");
                 PreparedStatement max = c.prepareStatement("select max(xmin::varchar::bigint) as txid from "+ vardbname)
                ) {
                c.setAutoCommit(false);

                while(true) {
                    stmts.clearParameters();

                    try(ResultSet rss = max.executeQuery()) {
                        if(rss.next()) {
                            nextTxId = rss.getLong(1);
                        }
                    }
                    stmts.setLong(1, previousTxId);
                    stmts.setLong(2, nextTxId + 1);
                    try(ResultSet rss = stmts.executeQuery()) {
                        while(rss.next()) {
                            String message = rss.getString("MESSAGE");
                            System.out.println("Message = " + message);
                            TextMessage mssg = session.createTextMessage(message);
                            System.out.println("Sent: " + mssg.getText());
                            producer.send(mssg);
                        }
                        previousTxId = nextTxId;
                    }
                    Thread.sleep(batchperiod2);
                }
            }
        }

基本上,代码用于获取数据库表中的内容并将其发送到ActiveMQ。当表更新时,它将发送刚更新的内容(不发送已发送的过去)。但是这段代码只适用于PostgreSQL

然后我打算创建一个“if”函数。所以我可以使用另一个数据库来获取数据(Oracle和MySQL)。

我想我必须改变这段代码吗?

 try(Connection c = DriverManager.getConnection("jdbc:postgresql://localhost:5432/"+ vardbserver, vardbuser, vardbpassword);
             PreparedStatement stmts = c.prepareStatement("SELECT * FROM "+ vardbname +" where xmin::varchar::bigint > ? and xmin::varchar::bigint < ? ");
             PreparedStatement max = c.prepareStatement("select max(xmin::varchar::bigint) as txid from "+ vardbname)
            ) {

2 个答案:

答案 0 :(得分:2)

一些思想补充了托尔斯滕的回答。

首先,xmin是一个系统列,即iirc,存储在磁盘上的行标题中。它由写入更新。我还没遇到交易ID没有增加的情况。但是,必须有一些回旋点。我认为你最好使用一个触发器,它将事务id存储在另一个表中,以便进行处理(并使用它来处理事物)。

对于Oracle和MySQL,底层存储是完全不同的,我不知道如何直接执行此操作。

如果您需要一个通用解决方案,您需要一个队列表,您可以使用触发器插入等待副本,然后从您的工作者中选择/删除。这可能在MySQL上比在PostgreSQL上更好,对于Oracle,你想要寻找面向索引的表。如果autovacuum无法跟上,请提出更多问题或聘请顾问。

经过进一步研究

InnoDB提供了类似的DB_TRX_ID列。请注意,如果运行MySQL,不能假设您拥有此列,因为MySQL具有不同的表存储引擎,而不是所有甚至支持事务。所以这是一个重要的限制。

我无法在Oracle上找到类似的专栏。

答案 1 :(得分:1)

这个脚本在一个表中间隔查找并放出自上一个循环以来所有插入的消息。

PostgreSQL存储插入记录的事务编号,因此可以用来查找新插入的记录(虽然我不确定新事务是否保证比以前的所有事务更高的数字作为脚本假定)。

其他DBMS没有此伪列。因此,您必须在表中添加时间戳列并使用此列。您必须更改两个查询以及与数据类型匹配的代码(我想java.sql.Timestamp而不是Long,但我不是Java人。)