- clou
-
* 回复内容中包含的链接未经审核,可能存在风险,暂不予完整展示!
在onCreate 方法中先把第一个fragment先装进去,
后面每次点相应的RadioButton就用transaction.replace方法来装另一个fragment,具体代码如下:
public class MainActivity extends Activity {
private FragmentTransaction transaction;
//这是三个fragment
private Homefragment mHomeFragment;
private Mintaofragment mMinTaoFragment;
private Servicefragment mServicefragment;
private RadioGroup mMainRadioGroup;
public View mMainView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main1);
mMainView = new View(this);
transaction = getFragmentManager().beginTransaction();
mHomeFragment = new Homefragment();
transaction.add(android.R.id.tabcontent, mHomeFragment);
t*********.commit();
mMainRadioGroup = (RadioGroup) findViewById(R.id.radiogroup);
mMainRadioGroup.setOnCheckedChangeListener(checkedChangeListener);
}
private OnCheckedChangeListener checkedChangeListener = new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.radio_home:
if (null == mHomeFragment) {
mHomeFragment = new Homefragment();
}
replaceFragment(mHomeFragment);
break;
case R.id.radio_mintao:
if (null == mMinTaoFragment) {
mMinTaoFragment = new Mintaofragment();
}
replaceFragment(mMinTaoFragment);
break;
case R.id.radio_service:
if (null == mServicefragment) {
mServicefragment = new Servicefragment();
}
replaceFragment(mServicefragment);
break;
default:
break;
}
}
};
public void replaceFragment(Fragment fragment) {
transaction = getFragmentManager().beginTransaction();
transaction.replace(android.R.id.tabcontent, fragment);
// Commit the transaction
t*********.commit();
}
}
Trans ID在贸易中什么含义 P/O NO中的 Trans Id含义?
P/O NO:PURCHASE ORDER NUMBER定单号码 Trans ID:Transaction ID,交易识别符(交易流水号)..2023-08-05 23:10:401
求助,如何获取交易数据和paypal的TransactionID-eBay外贸社区
交易数据在Sold已卖出商品的action下拉菜单找寻sales record点击。Paypal的Transaction ID去账户内点击单笔金流,页面上部有Transaction ID, 下部是交易详情。2023-08-05 23:10:481
苹果的transactionid会重吗
不会,根据查询苹果品牌相关资料显示,苹果的transactionid不会重。苹果公司是美国一家高科技公司,于1976年4月1日创立,并命名为美国苹果电脑公司,2007年1月9日更名为苹果公司,总部位于加利福尼亚州的库比蒂诺。2023-08-05 23:11:021
MYSQL的事务隔离级别,MVCC,readView和版本链小结
MVCC(Mutil-Version Concurrency Control),就是多版本并发控制。这种并发控制的方法,主要应用在RC和RR隔离级别的事务当中,利用执行select操作时,访问记录版本链,使得不同事物的读写,写读可以并发执行,提高系统性能。 Innodb 有两个隐藏字段 trx_id(事务id)和roll_pointer(回滚指针)。 transaction id : innoDB里面每个事务有一个唯一的事务ID,叫作transaction id,它是在事务开始的时候向InnoDB的事务系统申请的,是按申请顺序严格递增的。 roll_pointer : 指向上一事务版本的指针。 版本链 : 是一个单链表结构,对于同一行数据,每一个事务对其进行更新的时候都会产生一个新的版本,就会存储在这个链表当中。 一个存储事务id的列表。 readview的几个参数: m_ids:表示活跃事务id列表 min_trx_id:活跃事务中的最小事务id max_trx_id:已创建的最大事务id creator_trx_id:当前的事务id。 readview的生成时机: RC隔离级别:每次读取数据前,都生成一个readview; RR隔离级别:在第一次读取数据前,生成一个readview; 使用场景: [ 创建事务节点 ] 当我创建一个新的事务需要读取一行数据, 我会查询活跃的事务列表; 假设我当前的事务id是200, 当前活跃的事务id没有我的200, 因此需要去拷贝一个最新的不活跃事务并在版本链最后插入一个新节点200; mysql会去对比版本链和readView, 假设版本链数据为[1,50,100,150], 活跃列表为[100,150], 说明100和150都是未提交的活跃事务, 再向前一个节点50不在活跃事务列表说明事务50已经提交, 所以事务200拷贝事务50并插入版本链最后, 且将200追加到readView活跃列表的最后一个元素 [ 使用事务节点 ] 当我再次进行200号事务的查询或修改, 我需要读版本链的数据, 因为上一次操作已经在版本链做了200号节点, 因此我读的数据都是200号节点的数据, 这样就隔离了其他未提交的事务; 我的全部增删查改都在200号版本链上进行 [ readView实现事务隔离级别 ]以上两点都是基于隔离级别"读已提交"来进行说明的; 当mysql设置为"可重复读"时, 不同事务仍然是保存在版本链的不同节点上, 只不过新的事务创建的时候拷贝了当下的readView列表, 只要新事物不提交就一直使用这个拷贝的活跃列表; 假设此时100号数据提交了, 我在新事务执行了select 会去查活跃列表发现100号事务还是未提交状态, 因此读取到的还是50号事务提交的记录。 原子性,一致性,隔离性,持久性。 未提交读(read uncommitted)、提交读(read committed)、可重复读(repeatable read)、序列化读(serializable)2023-08-05 23:11:101
苹果订阅付费 app多账号订阅归属解决方案
本章不讨论 iOS订阅开发,详细的自行参考大神的文章 iOS 自动订阅开发 从上面文章得知,苹果设计自动订阅的初衷是 ,订阅一个服务, 这个服务需要跟着 Apple ID走 但国内的应用关联的是App的User ID,而不是Apple ID,但文章只是简单的描述“App自身做处理,就是记住首次购买的transaction-id,并且绑定某个用户”。 那么同一个Apple ID, A UID已订阅, B UID 购买订阅,客户端需要做哪些处理,后端做哪些处理呢? 本章只讨论多账号订阅的归属问题,与前后端的处理 receipt通过base64解码可得: “purchase-info”可以再次base64解码可得: 其他参数都可以在官网上查看到,这里重点看”original-transaction-id“与”transaction-id“ 现在假设 AppstoreConnect后台配置一个订阅 | product ID | 包月 | 包季 | | —— | —— | —— | | com.xx.autoVip | 10元 | 30元 | 同Apple ID情况下,未订阅的情况下 苹果这样的设计应该是为了收益最大化 知道苹果收费策略后,接下来多账号的就好办了 original-transaction-id 绑定到UserID上就可以了 订阅配置同上,同Apple ID情况下 用户订阅进行升降级,对于项目是减少了订阅的,A用户换绑B用户,其实A的订阅是失去的,所以尽量减少让用户换绑操作,其实一些运营策略也可以减少换绑概率,从而提高订阅收入2023-08-05 23:11:191
ora00600 内部错误代码 参数[qctcte1]
ORA-600[4137] transaction id不匹配,问题可能存在与回滚段中或者对象本身存在讹误 While backing out an undo record (i.e. at the time of rollback) we found a transaction id mis-match indicating either a corruption in the rollback segment or corruption in an object which the rollback segment is trying to apply undo records on.This would indicate a corrupted rollback segment. Undo/Redo description: While backing out an undo record (i.e. at the time of rollback) we found a transaction id mis-match indicating either a corruption in the rollback segment or corruption in an object which the rollback segment is trying to apply undo records on.这个需要patch undo来修复如果自己搞不定可以找诗檀软件专业ORACLE数据库修复团队成员帮您恢复!诗檀软件专业数据库修复团队2023-08-05 23:11:261
paypal transaction ID 这个东西从哪里能查到呀?
交易ID,指的就是你账户的交易记录,但不知你想查什么,PP-James2023-08-05 23:11:331
dns报文的transaction id随机生成吗
是的,接收到发送出的随机数来保证对应关系2023-08-05 23:11:411
顺序图的创建对象
在一个顺序图上注明对象的创建通常有两种方法。 首先,你可以用<>版型来发送一个消息,如同图2如...中所示OrderCheckout所示的那样。 其次,你可以通过把图中分类器位置下移,在其侧面调用一个消息的方式直接的显示创建,如你在图1所见的theStudent和图⒉的CreditCardPayment。直接方法的最主要的好处是它可以形象的表示出对象从无到有的逻辑。为软件消息使用操作符号。当一个消息被发给一个软件实现的分类器时,例如类、接口、或组件。通用的准则是使用实现语言的语法来描述消息名。 例如,在图3中,消息commit ( transactionID)被发送给source account对象,它使用了类似于Java、C++、和C_#语言的语法。为涉及人和组织角色的消息使用叙述性文字。当一条消息的来源或目标人或组织的角色时,需要使用简短的叙述性文字来描述传达的信息、来标记消息。 例如,在图1中,被student角色发送出的消息是provides name和provides student number,它们描述了这个人在做什么。推荐使用参数名称,而不是参数类型注意在图3中,大多数的消息都使用参数名称来注明参数,而不是使用类型。唯一的例外是start ()消息中传递的UserID参数。 这可以使你正确地判定该消息传递了什么值,有时候类型信息是不够的。 例如,消息addDeposit ( amount, target, transactionID)传达的信息要比addDeposit ( Currency, Account, int)多。2023-08-05 23:11:491
iOS iAP之自动订阅更换app账号
最近开发过程中遇到一个比较蛋疼的问题 前提:同一台手机,同一个苹果账号(沙盒测试账号) 用户用a账号登录你的app 购买了自动订阅的产品 退出a账号,登录b账号 继续点击会员订阅产品进行订阅,这时候苹果会给你一个弹窗Alert 告知你已经通过该苹果账号进行了订阅 按钮 :管理 或者好 点击管理 会跳转到系统的订阅管理界面 点击好 会收到支付成功的回调,同时还会有transactionID 和receiptdata如果本地按照支付成功的逻辑去校验服务器,服务器带着ReceiptData去苹果校验的时候会出现没有当前transactionID的情况. 所以这里需要服务端做一下判断,对于自动订阅的产品,如果没有当前的transactionID 不予以充值.2023-08-05 23:12:151
1. 简答题 已知a=-5.4,将a取整为-6,在matlab中如何实现?给出实现语句和运
首先我们需要定义锁的数据结构,这里定义的是一个锁的数据结构里有,事务的ID和锁的类型,我们这里用0来代表共享锁,1来代表排他锁。private class Lock{ TransactionId tid; int lockType; // 0 for shared lock and 1 for exclusive lock public Lock(TransactionId tid,int lockType){ this.tid = tid; this.lockType = lockType; } }1234567891012345678910然后我们需要定义一个锁管理中心(PageLockManager),用来判断是否能分配和释放锁,我们先来讲讲获取锁的逻辑。实现acquireLock函数,获取锁的逻辑:首先,我们获取锁时会获得当前事务的ID,要上锁的页面ID,锁的类型。我们需要在我们的锁表(lockMap)中查找看看是否,该页面已经上锁,如果没有上锁,根据事务ID创建传进来的锁,并存入锁表中,并返回True。如果该页面已经有锁则进入第三步。获取该页面的所有锁,找到等于当前事务的锁,看他是否满足如下情况:是否跟当前锁的类型一致,如果一致就可以获取锁。如果不一致,如果存在的锁是排他锁,那说明请求的锁是共享锁,也是可以直接获取的。这里涉及到一个知识点,**同一事务可以不断对某个数据对象加锁,不需要等锁的释放。**因为同一事务中所有操作都是串行化的,所以不会产生影响。如果不一致,如果存在的锁是共享锁,那说明请求的锁是排他锁,这里就涉及到一个锁升级的概念,如果当同一事务中只有共享锁,但是即将需要上排他锁时,此时可直接将共享锁升级为排他锁,这里的思想跟意向锁很想,同时官方文档中也提到了。如果当前事物在当前页面没有上过锁,那就看看该页面第一个锁是不是排他锁,如果是,按照封锁协议,其他事物都是不能加锁的,所以return False。同时如果当前页面上的锁都是共享锁,如果需要加的也是共享锁也就可以直接加上 return True,但是如果需要加上排他锁,根据共享锁的性质,排他锁将不被允许加上。2023-08-05 23:12:231
请教查看SQL SERVER操作日志详细记录的相关推荐
您好,很高兴为您解答。在SQL Server 7.0和SQL Server2000中,可以用下面的命令查看: DBCC log ( {dbid|dbname}, [, type={0|1|2|3|4}] ) 参数: Dbid or dbname - 任一数据库的ID或名字 type - 输出结果的类型: 0 - 最少信息(operation, context, transaction id) 1 - 更多信息(plus flags, tags, row length) 2 - 非常详细的信息(plus object name, index name,page id, slot id) 3 - 每种操作的全部信息 4 - 每种操作的全部信息加上该事务的16进制信息 默认 type = 0 要查看MSATER数据库的事务日志可以用以下命令: DBCC log (master)释放日志空间1.清空日志 DUMP TRANSACTION 库名 WITH NO_LOG 2.截断事务日志: BACKUP LOG 数据库名 WITH NO_LOG3.收缩数据库文件(如果不压缩,数据库的文件不会减小 企业管理器--右键你要压缩的数据库--所有任务--收缩数据库--收缩文件 --选择日志文件--在收缩方式里选择收缩至XXM,这里会给出一个允许收缩到的最小M数,直接输入这个数,确定就可以了 --选择数据文件--在收缩方式里选择收缩至XXM,这里会给出一个允许收缩到的最小M数,直接输入这个数,确定就可以了 也可以用SQL语句来完成 --收缩数据库 DBCC SHRINKDATABASE(客户资料) --收缩指定数据文件,1是文件号,可以通过这个语句查询到:select * from sysfiles DBCC SHRINKFILE(1)4.为了最大化的缩小日志文件(如果是sql 7.0,这步只能在查询分析器中进行) a.分离数据库: 企业管理器--服务器--数据库--右键--分离数据库 b.在我的电脑中删除LOG文件 c.附加数据库: 企业管理器--服务器--数据库--右键--附加数据库 此法将生成新的LOG,大小只有500多K 或用代码: 下面的示例分离 pubs,然后将 pubs 中的一个文件附加到当前服务器。 a.分离 E X E C sp_detach_db @dbname = "pubs" b.删除日志文件 c.再附加 E X E C sp_attach_single_file_db @dbname = "pubs", @physname = "c:/Program Files/Microsoft SQL Server/MSSQL/Data/pubs.mdf"5.为了以后能自动收缩,做如下设置: 企业管理器--服务器--右键数据库--属性--选项--选择"自动收缩" --SQL语句设置方式: E X E C sp_dboption "数据库名", "autoshrink", "TRUE"6.如果想以后不让它日志增长得太大 企业管理器--服务器--右键数据库--属性--事务日志 --将文件增长限制为xM(x是你允许的最大数据文件大小) --SQL语句的设置方式: alter database 数据库名 modify file(name=逻辑文件名,maxsize=20)特别注意: 请按步骤进行,未进行前面的步骤,请不要做后面的步骤 否则可能损坏你的数据库. 一般不建议做第4,6两步 第4步不安全,有可能损坏数据库或丢失数据 第6步如果日志达到上限,则以后的数据库处理会失败,在清理日志后才能恢复.另外提供一种更简单的方法,建议大家使用。更简单的方法: 1。右建数据库属性窗口--故障还原模型--设为简单 2。右建数据库所有任务--收缩数据库 3。右建数据库属性窗口--故障还原模型--设为大容量日志记录2023-08-05 23:12:312
Dhcp Enable是什么?
dhcp协议启用~路由自动分配ip地址这里有dhcp的解释http://baike.baidu.com/lemma-php/dispose/view.php/7992.htm2023-08-05 23:12:413
微信支付接口申请流程(二维码收款平台在线收款处理方法)
前言微信支付是企业级项目中经常使用的功能。作为后端开发人员,完全掌握这项技术是很有必要的。标志;徽标一、申请流程和步骤图1-1注册微信支付账号,获取微信小程序APPID,获取微信商户 商家ID,获取微信商家 API私钥,配置微信支付回调地址,绑定微信小程序与微信支付的关系,搭建SpringBoot项目,编写后台支付接口,发布部署接口服务项目,使用微信小程序或UniAPP调用微信支付功能,支付接口的包配置,openid的jwt或token分发。原微信小程序完成支付对接二、注册商家 2.1商户平台。商家或企业想通过微信支付销售商品,首先要通过微信平台注册商家。注册成功后会有商家信息等界面,包括账号信息,企业信息等等。如图2-1所示:图2-12.2商户id商户id是项目开发中的唯一id,是微信支付给予每一个商户或企业的唯一ID。也是客户拉起微信支付的凭据之一。 quot微信支付商户号 quot图2-1中是商家id。三、API私钥成功注册商家后,还可以在微信平台设置API私钥。如图3-1所示:图3-1API私钥也叫支付密钥,用户拉起微信支付时后台需要商户id和API密钥。四、商户签约微信支付产品商家可根据需求签约微信支付的产品,主要包括:JSAPI支付:商家调用微信支付提供的JSAPI接口,在支付场景中调用微信支付模块完成收款;原生支付:商家系统根据微信支付协议生成支付二维码,用户再使用微信 quot扫描 quot完成付款方式;小程序支付:在微信中通过分享给朋友或扫描二维码打开小程序,即可调用微信支付完成下单过程;支付码支付:用户出示微信钱包中的条码和二维码,商家扫描用户条码即可完成收款;刷脸支付:用户可以通过 quot刷脸 quot在整合了微信刷脸支付SDK的线下设备上。如图4-1所示:图4-1五、配置回调地址支付回拨地址是微信支付服务器返回给用户的支付信息的地址。如果商家签了微信小程序产品,支付回拨地址可以配置,也可以不配置。地址是公司的域名,或者没有配置。六、小程序获取APPID首先你要在官网:图6-1注册成功后,可以获得小程序的唯一APPID。如图6-2所示:图6-2七、微信支付与小程序绑定在微信支付平台绑定APPID。如图7-1所示:图7-1八、实战部分 8.1SpringBoot框架搭建首先创建一个初始化SpringBoot项目;在项目/模块的resources文件夹下编写properties/yml配置文件;开发环境和生产环境应该在配置文件中隔离;配置文件还包括服务器、数据库、spring、token、日志、时区、json格式、mybatis-plus、swagger、redis的全局统一配置,服务器配置,微信小程序配置等。项目基础架构后端接口控制器、与前端数据交互配置云服务器配置Swagger配置接口拦截器微信支付配置CommonConStanumsajaxresultsBaseController basentitypage页面所需的域接口和参数mappermapper文件接口serviceService:承担控制器层的接口方法定义。Impl:接口的具体实现逻辑。utils文件工具类Json工具类时间格式工具类第三方登录工具类8.2微信支付相关接口 8.2.1小程序用户登录接口。首先,用户需要在小程序上授权微信用户登录,调用接口获取。通过凭证可以交换用户的登录状态信息,包括当前小程序的唯一标识符、用户的唯一标识符以及本次登录的会话密钥。具体登录流程如图8-1所示:图8-1此时调用服务器接口,请求参数如图8-2所示:图8-2用户登录后返回的参数如图8-3所示:图8-38.2.2统一下单接口用户登录小程序后,在小程序页面拉起支付请求时,会调用统一下单界面。在拉起一个支付请求时,订单接口的参数需要两部分:一部分是商家和小程序相关的openid和appid,另一部分是商品相关的价格、名称、数量等参数。下面用代码详细解释一下微信支付接口。代码以REST风格的API接口形式编写。统一订购界面@ API operation@ request mappingpublic Ajax result unified order{//验证小程序用户的登录//查询数据库订单信息//只有未付款的订单才能发起支付//0元购买未付款/* *设置与商户和小程序相关的请求参数* *//获取小程序的appid字符串appid=wxmauil.getappid;WxPayUnifiedOrderRequest WxPayUnifiedOrderRequest=new WxPayUnifiedOrderRequest;wxpayunifieorderequest . set appId;//商品名称string body=sysorderscout . getcourename;body=body.length 40?body.substring:body;wxpayunifieorderequest . set body;//订单编号WXPayUnifiedOrder请求。SetOutTradeNo);//订单金额wxpayunifiedorequest . settotalfee。multiply )。int value);//事务类型wxpayunifiedorequest . settradetype;//支付回调地址wxpayunifiedorequest . setnotifyurl#039;/wx/API/order/notify-order );wxpayunifiederrequest . setspbillcreateip;//当前applet中用户的唯一标识符wxpayunifiedorerrequest . set OpenID);//调用微信服务类wxpayservice wxpayservice=wxpayconfiguration . getpayservice;返回Ajax result . success);} 8.2.3创建订单接口创建订单界面用户可以在商品页面下一个商品的订单,这个时候就需要为用户创建一个购买商品的订单。流程是通过接口请求用户信息、商品信息等参数,经过逻辑判断后创建新订单,最后返回订单所需数据。@ API operation@ request mappingpublic Ajax result create{//微信用户信息//判断是否购买了同款产品。如果有,则不能新建订单//在满足条件后将数据插入数据库wxOrderResponse wxOrderResponse=orderservice . add;//如果新增失败,则提示If{ return Ajax result . error会被退回;}返回Ajax result . success;} 8.2.4取消订单接口取消订单界面当用户拉起微信支付时,如果在支付界面点击取消支付,则该操作视为取消订单的支付,此时订单的支付状态应显示在订单页面。该接口可以将订单id作为请求参数,首先确定数据库中是否存在订单信息,然后限制可以取消的订单类型,最后更新数据库表状态。@ API operation@ request mappingpublic Ajax result cancel{//判断订单是否有sys orders sys orders=sysorderservice . get byid;if{ return Ajax result . error;}//只有未付款的订单才能取消,如果){ return Ajax result . error,MyReturnCode。ERR _ 70001 . getmsg);} sysordersservice . order cancel;返回Ajax result . success;} 8.2.5订单详情接口订单明细界面当订单生成后,用户可以在页面上查看货物订单的详细信息。界面可以通过订单id从数据库中获取详细信息,该页面显示的数据由业务需求决定。@ API operation@ request mapping@ apimplicitparams})公共Ajax结果myorderDetail{//从数据库获取详细参数sysorderdetailresponse=sysorderservice . Get detail;返回Ajax result . success;}订单详细信息逻辑/* * *订单详情页面参数处理* @ param orderId * @ return sysorderdetail response */@ override public sysorderdetail response get detail{ SysOrderDetailResponse SysOrderDetailResponse=Order mapper . get detail;//处理页面字符串phone num=sysorderdetailresponse . get mobile的手机号码;sysorderdetailresponse . set mobile ****#039;phoneNum.substring);//根据不同的订单状态显示不同的数据。//计算剩余待支付时间并显示返回sysOrderDetailResponse} 8.2.6支付回调接口微信支付回拨是用户支付货款后,将数据发送到微信服务器,然后微信服务器将支付结果返回给用户和商家的过程。其中主要关注的是用户支付-微信回拨判断-数据库修改的流程。支付回拨接口@ API operation@请求映射公共字符串通知订单引发WxPayException { log . info;//微信支付服务WxPayService WxPayService=wxpayconfiguration。getpayservice;WxPayOrderNotifyResult notifyResult=wxpayservice。parseordernotifyresult;log . info;//对创建的订单进行支付系统订单系统订单=订单服务。获取一个);if { if.相乘).int value==通知结果。gettotalfee){ String time end=notify结果。gettime end;本地日期时间付款时间=本地日期时间效用。解析;//支付时间sysOrders.setPaymentTime;系统订单。setorderamount);//微信订单编号系统订单。settransactionid);//更新数据库订单服务。通知订单;log . info);返回wxpaynotifyresponse . success;} else { return wxpaynotifyresponse。失败;} } else { return wxpaynotifyresponse。失败;}}其中,notifyOrder方法的作用是在支付成功后在数据库更新订单的状态。通知订单方法@ Override @ Transactional公共void通知订单{//只有未支付订单能操作,即is_pay字段为0的订单if){//更新订单支付状态系统订单。setispay;系统订单。设置状态);系统订单映射器。更新byid;//更新商品表状态//更新订单生命周期表}}至此,Spring Boot中的微信支付全过程已经分享完成。如有不足,望大家指正。王者之心2点击试玩2023-08-05 23:12:481
java 数据库事务与应用事务的区别
在说他们之间的区别之前,先考虑如下几个问题: 1、getCurrentSession()与openSession()的区别? * 采用getCurrentSession()创建的session会绑定到当前线程中,而采用openSession() 创建的session则不会 * 采用getCurrentSession()创建的session在commit或rollback时会自动关闭,而采用openSession() 创建的session必须手动关闭 2、使用getCurrentSession()需要在hibernate.cfg.xml文件中加入如下配置: * 如果使用的是本地事务(jdbc事务) <property name="hibernate.current_session_context_class">thread</property> * 如果使用的是全局事务(jta事务) <property name="hibernate.current_session_context_class">jta</property> 以上是hibernate中一些使用,下面来说说jdbc与jta的区别: JDBC 事务 JDBC 事务是用 Connection 对象控制的。JDBC Connection 接口( java.sql.Connection )提供了两种事务模式:自动提交和手工提交。 #在jdbc中,事务操作缺省是自动提交。也就是说,一条对数据库的更新表达式代表一项事务操作,操作成功后,系统将自动调用commit()来提交,否则将调用rollback()来回滚。 # 在jdbc中,可以通过调用setAutoCommit(false)来禁止自动提交。之后就可以把多个数据库操作的表达式作为一个事务,在操作完成后调 用commit()来进行整体提交,倘若其中一个表达式操作失败,都不会执行到commit(),并且将产生响应的异常;此时就可以在异常捕获时调用 rollback()进行回滚。这样做可以保持多次更新操作后,相关数据的一致性,示例如下: try { conn = DriverManager.getConnection ("jdbc:oracle:thin:@host:1521:SID","username","userpwd"; conn.setAutoCommit(false);//禁止自动提交,设置回滚点 stmt = conn.createStatement(); stmt.executeUpdate(“alter table …”); //数据库更新操作1 stmt.executeUpdate(“insert into table …”); //数据库更新操作2 conn.commit(); //事务提交 }catch(Exception ex) { ex.printStackTrace(); try { conn.rollback(); //操作不成功则回滚 }catch(Exception e) { e.printStackTrace(); } } JDBC 事务的一个缺点是事务的范围局限于一个数据库连接。一个 JDBC 事务不能跨越多个数据库。 JTA事务 JTA(Java Transaction API) 为 J2EE 平台提供了分布式事务服务。 要用 JTA 进行事务界定,应用程序要调用 javax.transaction.UserTransaction 接口中的方法。例如: utx.begin(); // ... DataSource ds = obtainXADataSource(); Connection conn = ds.getConnection(); pstmt = conn.prepareStatement("UPDATE MOVIES ..."); pstmt.setString(1, "Spinal Tap"); pstmt.executeUpdate(); // ... utx.commit(); 让我们来关注下面的话: “用 JTA 界定事务,那么就需要有一个实现 javax.sql.XADataSource 、 javax.sql.XAConnection 和 javax.sql.XAResource 接口的 JDBC 驱动程序。一个实现了这些接口的驱动程序将可以参与 JTA 事务。一个 XADataSource 对象就是一个 XAConnection 对象的工厂。 XAConnection s 是参与 JTA 事务的 JDBC 连接。” 要使用JTA事务,必须使用XADataSource来产生数据库连接,产生的连接为一个XA连接。 XA连接(javax.sql.XAConnection)和非XA(java.sql.Connection)连接的区别在于:XA可以参与JTA的事务,而且不支持自动提交。 注意: Oracle, Sybase, DB2, SQL Server等大型数据库才支持XA, 支持分布事务。 My SQL 连本地都支持不好,更别说分布事务了。 JTA方式的实现过程: 用XADataSource产生的XAConnection它扩展了一个getXAResource()方法,事务通过这个方法把它加入到事务容器中进行 管理.对于调用者来说,根本看不到事务是如果管理的,你只要声明开始事务,告诉容器我下面的操作要求事务参与了,最后告诉事务说到这儿可以提交或回滚了, 别的都是黑箱操作。 在使用JTA之前,你必须首先实现一个Xid类用来标识事务(在普通情况下这将由事务管理程序来处理)。Xid包含三个元素:formatID、gtrid(全局事务标识符)和bqual(分支修饰词标识符)。 下面的例子说明Xid的实现: import javax.transaction.xa.*; public class MyXid implements Xid { protected int formatId; protected byte gtrid[]; protected byte bqual[]; public MyXid() { } public MyXid(int formatId, byte gtrid[], byte bqual[]) { this.formatId = formatId; this.gtrid = gtrid; this.bqual = bqual; } public int getFormatId() { return formatId; } public byte[] getBranchQualifier() { return bqual; } public byte[] getGlobalTransactionId() { return gtrid; } } 其次,你需要创建一个你要使用的数据库的数据源: public DataSource getDataSource() throws SQLException { SQLServerDataSource xaDS = new com.merant.datadirect.jdbcx.sqlserver.SQLServerDataSource(); xaDS.setDataSourceName("SQLServer"); xaDS.setServerName("server"); xaDS.setPortNumber(1433); xaDS.setSelectMethod("cursor"); return xaDS; } 例1 这个例子是用“两步提交协议”来提交一个事务分支: XADataSource xaDS; XAConnection xaCon; XAResource xaRes; Xid xid; Connection con; Statement stmt; int ret; xaDS = getDataSource(); xaCon = xaDS.getXAConnection("jdbc_user", "jdbc_password"); xaRes = xaCon.getXAResource(); con = xaCon.getConnection(); stmt = con.createStatement(); xid = new MyXid(100, new byte[]{0x01}, new byte[]{0x02}); try { xaRes.start(xid, XAResource.TMNOFLAGS); stmt.executeUpdate("insert into test_table values (100)"); xaRes.end(xid, XAResource.TMSUCCESS); ret = xaRes.prepare(xid); if (ret == XAResource.XA_OK) { xaRes.commit(xid, false); } } catch (XAException e) { e.printStackTrace(); } finally { stmt.close(); con.close(); xaCon.close(); } 当然,实际过程中,我们不需要写这些代码,这些代码是JTA最终的实现代码。 关于“两步提交协议”,可以参看下面的文章: http://www.ibm.com/developerworks/cn/db2/library/techarticles/dm-0505weber/index.html两阶段提交(Two-Phase-Commit)协议 首先,两阶段提交(Two-Phase-Commit)事务的启动与常规的单阶段提交(One-Phase-Commit)事务类似。接着,应用程序/客 户机对该两阶段提交(Two-Phase-Commit)操作中所涉及的所有数据库执行其修改工作。现在,在最终提交该事务之前,客户机通知参与的数据库准备提交(第 1 阶段)。如果客户机从数据库收到一条“okay”,就发出命令向数据库提交该事务(第 2 阶段)。最后分布式事务(Distributed Transaction)结束。 上面的例子演示了如何在 Java 中使用 JTA 实现两阶段提交(Two-Phase-Commit)协议。在该应用程序中,如果一个事务分支报告了错误,您就要负责进行错误处理。但是“两阶段提交协议 简介”小节中提到仍然存在一个问题,那就是如果第 2 阶段中一个事务分支发生故障,该怎么办呢? 如果再次查看程序代码,您可以看到在“第 1 阶段”和“第 2 阶段”之间有一个很小的时间间隔。在这一时间间隔中,出于某种理由,其中某一参与数据库可能崩溃。如果发生了,我们将陷入分布式事务已经部分提交的情形中。 假 定下列情形:在“第 1 阶段”之后,您从 DB2 和 IDS 数据库中都收到了“okay”。在下一步中,应用程序成功提交了 DB2 的事务分支。接着,应用程序通知 DB2 事务分支提交事务。现在,在应用程序可以通知 IDS 事务分支提交它这一部分之前,IDS 引擎由于断电发生崩溃。这就是一种部分提交全局事务的情形。您现在该怎么办呢? 在重启之后,DB2 和 IDS 都将尝试恢复打开的事务分支。该引擎等待来自应用程序的提示如何做。如果应用程序没有准备重新发送“第 2 阶段”的提交,该事务分支将被引擎所启动的试探性回滚中止。这是非常糟糕的,因为这将使该全局事务处于不一致状态。 一种解决方案是用一个小型应用程序连接引擎中打开的事务分支,并通知引擎提交或回滚这一打开的事务。如果您使用 IDS 作为后端,那么还有一个隐藏的 onmode 标志,允许您结束打开的事务分支。(onmode -Z xid)。 在 DB2 UDB 中,您可以发出 LIST INDOUBT TRANSACTIONS 来获得打开的 XA 事务的有关信息。您必须查看 DB2 Information Center 中的描述来解决该问题。 上面描述的情形是一个很好的例子,也是使用应用程序服务器(Application Server)或事务监控器(Transaction Monitor)的理由。在使用一个中间层服务器时,就由该服务器负责保持事情正常。2023-08-05 23:12:571
DHCP是什么意思?
DHCP是英文Dynamic Host Configuration Protocol的缩写,意思是动态主机配置协议。DHCP可以自动为通过TCP/IP协议登录到主机上的客户机分配IP地址,省去了手动设置IP地址的繁琐性.2023-08-05 23:13:075
打不开oracle数据库,公司的 Oracle数据库打不开了,一open就报错Ora-00600该
如果自己搞不定可以找诗檀软件专业ORACLE数据库修复团队成员帮您恢复!诗檀软件专业数据库修复团队Oracle的损坏/坏块 主要分以下几种:ORA-1578ORA-8103ORA-1410ORA-1499ORA-1578ORA-81##ORA-14##ORA-26040ORA-600 ErrorsBlock CorruptionIndex CorruptionRow CorruptionUNDO CorruptionControl FileConsistent ReadDictionaryFile/RDBA/BLError Description Corruption related to: ORA-1578 ORA-1578一般为Oracle检测到存在物理坏块问题,包括其检测数据块中的checksum不正确,或者tail_chk信息不正确等。 ORA-1578 is reported when a block is thought to be corrupt on read. Block数据块OERR: ORA-1578 “ORACLE data block corrupted (file # %s, block # %s)” Master Note OERR: ORA-1578 “ORACLE data block corrupted (file # %s, block # %s)” Fractured Block explanationHandling Oracle Block Corruptions in Oracle7/8/8i/9i/10g/11g Diagnosing and Resolving 1578 reported on a Local Index of a Partitioned table ORA-1410 ORA-1410错误常见于从INDEX或其他途径获得的ROWID,到数据表中查询发现没有对应的记录。该错误可能因为数据表与其索引存在不一致,也可能是分区的数据表本身存在问题。 This error is raised when an operation refers to a ROWID in a table for which there is no such row.The reference to a ROWID may be implicit from a WHERE CURRENT OF clause or directly from a WHERE ROWID=… clause.ORA 1410 indicates the ROWID is for a BLOCK that is not part of this table. Row数据行Understanding The ORA-1410 Summary Of Bugs Containing ORA 1410 OERR: ORA 1410 “invalid ROWID” ORA-8103 该ORA-8103可能由多个BUG引起,例如LOB在10.2.0.4之前可能会由于BUG覆盖了另一张表的segment header,导致出现ORA-8103错误。诊断该问题可以从数据表的segment header和data_object_id入手。 The object has been deleted by another user since the operation began.If the error is reproducible, following may be the reasons:-a.) The header block has an invalid block type.b.) The data_object_id (seg/obj) stored in the block is different than the data_object_id stored in the segment header. See dba_objects.data_object_id and compare it to the decimal value stored in the block (field seg/obj). Block数据块ORA-8103 Troubleshooting, Diagnostic and Solution OERR: ORA-8103 “object no longer exists” / Troubleshooting, Diagnostic and Solution ORA-8102 ORA-8102常见于索引键值与表上存的值不一致。 An ORA-08102 indicates that there is a mismatch between the key(s) stored in the index and the values stored in the table. What typically happens is the index is built and at some future time, some type of corruption occurs, either in the table or index, to cause the mismatch. Index索引OERR ORA-8102 “index key not found, obj# %s, file %s, block %s (%s) ORA-1499 对表和索引做交叉验证时发现问题 An error occurred when validating an index or a table using the ANALYZE command.One or more entries does not point to the appropriate cross-reference. Index索引ORA-1499. Table/Index row count mismatch OERR: ORA-1499 table/Index Cross Reference Failure – see trace file ORA-1498 Generally this is a result of an ANALYZE … VALIDATE … command.This error generally manifests itself when there is inconsistency in the data/Index block. Some of the block check errors that may be found:-a.) Row locked by a non-existent transactionb.) The amount of space used is not equal to block sizec.) Transaction header lock count mismatch.While support are processing the tracefile it may be worth the re-running the ANALYZE after restarting the database to help show if the corruption is consistent or if it ‘moves".Send the tracefile to support for analysis.If the ANALYZE was against an index you should check the whole object. Eg: Find the tablename and execute:ANALYZE TABLE xxx VALIDATE STRUCTURE CASCADE; Block OERR: ORA 1498 “block check failure – see trace file” ORA-26040 由于采用过nologging/unrecoverable选项的redo生成机制,且做过对应的recover,导致数据块中被填满了0XFF,导致报错ORA-26040。 Trying to access data in block that was loaded without redo generation using the NOLOGGING/UNRECOVERABLE option.This Error raises always together with ORA-1578 Block数据块OERR ORA-26040 Data block was loaded using the NOLOGGING option ORA-1578 / ORA-26040 Corrupt blocks by NOLOGGING – Error explanation and solution ORA-1578 ORA-26040 in a LOB segment – Script to solve the errors ORA-1578 ORA-26040 in 11g for DIRECT PATH with NOARCHIVELOG even if LOGGING is enabled ORA-1578 ORA-26040 On Awr Table Errors ORA-01578, ORA-26040 On Standby Database Workflow Tables ORA-01578 ORACLE data block corrupted ORA-26040 Data block was loaded using the NOLOGGING option ORA-1578, ORA-26040 Data block was loaded using the NOLOGGING option ORA-600[12700] 从索引获得的ROWID,对应到数据表时发现不存在数据行错误。一把是一致性度consistent read问题 Oracle is trying to access a row using its ROWID, which has been obtained from an index.A mismatch was found between the index rowid and the data block it is pointing to. The rowid points to a non-existent row in the data block. The corruption can be in data and/or index blocks.ORA-600 [12700] can also be reported due to a consistent read (CR) problem. Consistent Read一致性读Resolving an ORA-600 [12700] error in Oracle 8 and above. ORA-600 [12700] “Index entry Points to Missing ROWID” ORA-600[3020] 主要问题是redo和数据块中的信息不一致 This is called a ‘STUCK RECOVERY".There is an inconsistency between the information stored in the redo and the information stored in a database block being recovered. Redo ORA-600 [3020] “Stuck Recovery” Information Required for Root Cause Analysis of ORA-600 [3020] (stuck recovery) ORA-600[4194] 主要是redo记录与回滚rollback/undo的记录不一致 A mismatch has been detected between Redo records and rollback (Undo) records.We are validating the Undo record number relating to the change being applied against the maximum undo record number recorded in the undo block.This error is reported when the validation fails. Undo ORA-600 [4194] “Undo Record Number Mismatch While Adding Undo Record” Basic Steps to be Followed While Solving ORA-00600 [4194]/[4193] Errors Without Using Unsupported parameter ORA-600[4193] 主要是redo记录与回滚rollback/undo的记录不一致 A mismatch has been detected between Redo records and Rollback (Undo) records.We are validating the Undo block sequence number in the undo block against the Redo block sequence number relating to the change being applied.This error is reported when this validation fails. Undo ORA-600 [4193] “seq# mismatch while adding undo record” Basic Steps to be Followed While Solving ORA-00600 [4194]/[4193] Errors Without Using Unsupported parameter Ora-600 [4193] When Opening Or Shutting Down A Database ORA-600 [4193] When Trying To Open The Database ORA-600[4137] transaction id不匹配,问题可能存在与回滚段中或者对象本身存在讹误 While backing out an undo record (i.e. at the time of rollback) we found a transaction id mis-match indicating either a corruption in the rollback segment or corruption in an object which the rollback segment is trying to apply undo records on.This would indicate a corrupted rollback segment. Undo/Redo ORA-600 [4137] “XID in Undo and Redo Does Not Match” ORA-600[6101] Not enough free space was found when inserting a row into an index leaf block during the application of undo. Index ORA-600 [6101] “insert into leaf block (undo)” ORA-600[2103] Oracle is attempting to read or update a generic entry in the control file.If the entry number is invalid, ORA-600 [2130] is logged. Control File ORA-600 [2130] “Attempt to access non-existant controlfile entry” ORA-600[4512] Oracle is checking the status of transaction locks within a block.If the lock number is greater than the number of lock entries, ORA-600 [4512] is reported followed by a stack trace, process state and block dump.This error possibly indicates a block corruption. Block ORA-600 [4512] “Lock count mismatch” ORA-600[2662] 主要是发现一个数据块的SCN甚至超过了当前SCN,常规解决途径有调整SCN等,但11.2以后Oracle公司使较多调整SCN的方法失效了 A data block SCN is ahead of the current SCN.The ORA-600 [2662] occurs when an SCN is compared to the dependent SCN stored in a UGA variable.If the SCN is less than the dependent SCN then we signal the ORA-600 [2662] internal error. Block ORA-600 [2662] “Block SCN is ahead of Current SCN” ORA 600 [2662] DURING STARTUP ORA-600[4097] 访问一个回滚段头以便确认事务是否已提交时,发现XID有问题 We are accessing a rollback segment header to see if a transaction has been committed.However, the xid given is in the future of the transaction table.This could be due to a rollback segment corruption issue OR you might be hitting the following known problem. Undo2023-08-05 23:13:521
如何读懂SQL Server的事务日志
SQL Server中的事务日志无疑是SQL Server中最重要的部分之一。因为SQL SERVER利用事务日志来确保持久性(Durability)和事务回滚(Rollback)。从而还部分确保了事务的ACID属性.在SQL Server崩溃时,DBA还可以通过事务日志将数据恢复到指定的时间点。当SQL Server运转良好时,多了解一些事务日志的原理和概念显得并不是那么重要。但是,一旦SQL SERVER发生崩溃时,了解事务日志的原理和概念对于快速做出正确的决策来恢复数据显得尤为重要.本系列文章将会从事务日志的概念,原理,SQL Server如何使用日志来确保持久性属性等方面来谈SQL Server的事务日志.事务日志的物理组织构架事务日志仅仅是记录与其对应数据库上的事务行为和对数据库修改的日志文件.在你新建数据库时,伴随着数据库文件,会有一个默认以ldf为扩展名的事务日志文件. 当然,一个数据库也可以配有多个日志文件,但是在逻辑上,他们可以看成一个.在SQL Server对于日志文件的管理,是将逻辑上一个ldf文件划分成多个逻辑上的虚拟日志文件(virtual log files,简称VLFs).以便于管理。那为什么SQL Server要把日志文件划分出多个VLFS呢?因为SQL Server通过这种方式使得存储引擎管理事务日志更加有效.并且对于日志空间的重复利用也会更加高效。使用VLF作为收缩数据库的最小单位比使用ldf文件作为最小单位无疑是更加高效的.VLFS的个数和大小无法通过配置进行设定,而是由SQL Server进行管理.当Create或Alter数据库时,SQL Server通过ldf文件的大小来决定VLFS的大小和数量。在日志文件增长时,SQL Server也会重新规划VLFS的数量.注意:根据这个原理不难看书,如果设置日志文件的增量过小,则会产生过多的VLFS,也就是日志文件碎片,过多的日志文件碎片会拖累SQL Server性能.事务日志的逻辑组织构架当针对数据库对象所做的任何修改保存到数据库之前,相应的日志首先会被记录到日志文件。这个记录会被按照先后顺序记录到日志文件的逻辑末尾,并分配一个全局唯一的日志序列号(log sequence number,简称LSN),这个序列号完全是按照顺序来的,如果日志中两个序列号LSN2>LSN1,则说明LSN2所在LSN1之后发生的.由此可以看出,将日志文件分为多个文件除了磁盘空间的考虑之外。完全不会像数据那样可以并行访问,所以将日志文件分为多个完全不会有性能上的提升.LSN号可以看作是将日志文件和其记录数据之间的纽带.每一条日志不仅有LSN号,还有其对应事务的事务日志,许多类型的操作都记录在事务日志中。查看SQL SERVER的事务日志在SQL SERVER 7.0和2000中,可以用下面的命令查看:DBCC log ( {dbid|dbname}, [, type={0|1|2|3|4}] )参数:Dbid or dbname - 任一数据库的ID或名字type - 输出结果的类型:0 - 最少信息(operation, context, transaction id)1 - 更多信息(plus flags, tags, row length)2 - 非常详细的信息(plus object name, index name,page id, slot id)3 - 每种操作的全部信息4 - 每种操作的全部信息加上该事务的16进制信息默认 type = 0要查看MSATER数据库的事务日志可以用以下命令:DBCC log (master)一般情况下可以借助其他工具来查看SQL SERVER的事务日志,如LOG EXPLOERE等2023-08-05 23:14:021
华为手机如何制作手机号
手机虚拟号码生成器。基于华为云的虚拟号码,生成的带有真实用户的模拟手机号码,可直接使用。支持通过API方式调用,增加或减少应用发送短信时的业务逻辑。您可通过手机方式,生成随机数或者生成动态密码。生成的随机数由应用生成,且只能由应用侧调用,不具备独立性。生成的手机号码可以是一个用于接收短信内容、随机数、验证码、通知短信的服务,或者其它服务的手机号码。//引用的是真实手机号码,短信接口不支持使用平台预置的手机号。//引用的是模拟验证码短信,短信接口不支持使用平台预置的“验证码短信”。//引用的是自定义的短信签名,短信签名请输入对应的签名名称。在应用开发工作台左侧列表单击,选择“应用管理。在应用预览页,单击“新增测试”,开始新增测试短信。根据接口参数“userData”、“statusData”,输入短信接收者的手机号和验证码,单击“确定”。短信模板是指在短信应用关联的短信模板中,根据参数“templateId”参数值对变量进行设置的。如果变量设置为“templateId”,需要在变量的“变量类型”中选择“固定文本”,并输入“{!$GlobalTransactionID}”。如果变量设置为“status”,需要在变量的“值”中设置“status”。例如,您设置了名为“status”的变量为“{!$GlobalTransactionID}”,“值”为“status”,“status”为“status”。2023-08-05 23:14:211
求一个能把EXCEL批量导入SQL数据库的ASP程序代码!!!
只会导入到oracle2023-08-05 23:14:295
IOS内购票据字段
"receipt": { "original_purchase_date_pst": "2019-07-17 19:01:20 America/Los_Angeles", //原始购买时间,美国洛杉矶时间 "purchase_date_ms": "1563415280644", //购买时间毫秒(进行时间戳转行可得到北京时间) "unique_identifier": "5e31a30d27be905f459fdca00aab2ebcf7045d22", //唯一标识符 "original_transaction_id": "1000000548076202", //原始交易ID "bvrs": "0", //iPhone程序的版本号 "transaction_id": "1000000548076202", //交易的标识 "quantity": "1", //购买商品的数量 "unique_vendor_identifier": "DD2CA653-2F36-445F-99CB-8C403E4B4536", //开发商交易ID "item_id": "1471296882", //App Store用来标识程序的字符串 "version_external_identifier": "0", //识别购买时使用的App版本,为任意数字 "bid": "com.wusheng.wssgz", //iPhone程序的bundle标识 "is_in_intro_offer_period": "false", //是否在享受折扣价 "product_id": "Sg.WSsgZ.ws.803", //商品的标识 "purchase_date": "2019-07-18 02:01:20 Etc/GMT", //购买的格林威治时间(与北京时间相差8小时) "is_trial_period": "false", //是否是免费试用 "purchase_date_pst": "2019-07-17 19:01:20 America/Los_Angeles", //购买时间,美国洛杉矶时间 "original_purchase_date": "2019-07-18 02:01:20 Etc/GMT", //原始购买的格林威治时间(与北京时间相差8小时) "original_purchase_date_ms": "1563415280644" //(原始购买时间进行时间戳转行可得到北京时间) }, "status": 0 //校验状态码 } (校验票据时重点校验部分为红色标注部分) 状态码详解2023-08-05 23:14:431
iOS IAP支付防丢单问题
我们先来看看有哪些请况会发生掉单: -(void)restoreCompletedTransactions; Use this method to restore finished transactions—that is, transactions for which you have already called finishTransaction: . You call this method in one of the following situations: 也就是说这个方法无法恢复非续订订阅 . 我必须自己存储购买并实现自己的恢复功能 . 然而我在测试的过程中发现上诉第一种异常情况的订单可以通过这个方法触发这个回调 是不是很很诡异,,此处有待大神们的再次验证! 国内连接苹果服务器的稳定性 开发之初,苹果方就很负责的告知:我们的服务器不稳定。真正开发之后,发现苹果方果然是很负责的,不仅是不稳定,而且足够慢。app store server验证一个收据需要3-6s时间 1、程序加入支付队列使用SKMutablePayment和SKPayment的区别 两者拥有的属性一样,唯一区别是属性读写权限不同,SKMutablePayment属性具有读写权限,SKPayment属性只读,如果你要使用applicationUsername透传字段,那么就一定要使用SKMutablePayment加入支付队列 2、透传字段applicationUsername可能返回的是nil 在支付完成后,每笔订单都不调用finishTransaction,如此测试四五笔订单后,重新启动该应用,苹果自动补单会进行,在有些时候该字段就会为空,需要开发者注意 3、updatedTransactions:在App整个生命周期只会走一次,所以只要不把订单finishTransaction掉,重启App就会重新走苹果的补单流程(自动调用updatedTransactions:注意需要[[SKPaymentQueue defaultQueue] addTransactionObserver:instance];添加观察者才可以),逻辑需要自己根据项目实现 4、SKPaymentTransaction *transaction属性官方说明 5、 transaction.transactionDate 将订单交易添加到服务器队列的日期,仅当状态为SKPaymentTransactionStatePurchased或SKPaymentTransactionStateRestored时有效 6、 transaction.transactionIdentifier transactionIdentifier是唯一标识交易支付成功的字符串,此值的格式与收据中的事务transaction_id相同,但是值可能不相同,仅当状态为SKPaymentTransactionStatePurchased或SKPaymentTransactionStateRestored时有效 7、transaction.originalTransaction 原始交易id,仅当状态为SKPaymentTransactionStateRestored时有效有值 8、 transaction.payment.applicationUsername 获取之前设置的applicationUsername 9、 transactionReceiptData可以无限验证通过,也就是说一个凭证可以被校验多次,这是刷单方法之一,需要开发者注意,有开发者说苹果的补单流程返回的transactionReceiptData即使同一笔订单也会变,测试下来并不会变化 10、transactionReceiptData验证解析后,in_app字段出现为空或者多个购买项目,按照网上部分开发者说法,只要不finishTransaction掉订单,下次再支付成功后,返回的transactionReceiptData凭证,就是包含之前的购买记录,测试多次无法复现2023-08-05 23:14:501
龙管家SQL Server数据库里面管理员账号和密码怎么查看?
安装好Win2003自带的iis后,其它一切正常,打开时提示“数据库服务未开启或连接出错,请与系统管理员联系!”,如何解决!!!求助,在线等!!!2023-08-05 23:14:582
与MySQL传统复制相比,GTID有哪些独特的复制姿势
前言GTID(Global Transaction ID)是MySQL5.6引入的功能,可以在集群全局范围标识事务,用于取代过去通过binlog文件偏移量定位复制位置的传统方式。借助GTID,在发生主备切换的情况下,MySQL的其它Slave可以自动在新主上找到正确的复制位置,这大大简化了复杂复制拓扑下集群的维护,也减少了人为设置复制位置发生误操作的风险。另外,基于GTID的复制可以忽略已经执行过的事务,减少了数据发生不一致的风险。GTID虽好,要想运用自如还需充分了解其原理与特性,特别要注意与传统的基于binlog文件偏移量复制方式不一样的地方。本文概述了关于GTID的几个常见问题,希望能对理解和使用基于GTID的复制有所帮助。GTID长什么样根据官方文档定义,GTID由source_id加transaction_id构成。GTID = source_id:transaction_id上面的source_id指示发起事务的MySQL实例,值为该实例的server_uuid。server_uuid由MySQL在第一次启动时自动生成并被持久化到auto.cnf文件里,transaction_id是MySQL实例上执行的事务序号,从1开始递增。 例如:e6954592-8dba-11e6-af0e-fa163e1cf111:1一组连续的事务可以用‘-‘连接的事务序号范围表示。例如e6954592-8dba-11e6-af0e-fa163e1cf111:1-5更一般的情况是GTID的集合。GTID集合可以包含来自多个source_id的事务,它们之间用逗号分隔;如果来自同一source_id的事务序号有多个范围区间,各组范围之间用冒号分隔,例如:e6954592-8dba-11e6-af0e-fa163e1cf111:1-5:11-18,e6954592-8dba-11e6-af0e-fa163e1cf3f2:1-27即,GTID集合拥有如下的形式定义:gtid_set:uuid_set [, uuid_set] ...| ‘‘uuid_set:uuid:interval[:interval]...uuid:hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhhh:[0-9|A-F]interval:n[-n](n >= 1)如何查看GTID可以通过MySQL的几个变量查看相关的GTID信息。gtid_executed在当前实例上执行过的GTID集合; 实际上包含了所有记录到binlog中的事务。所以,设置set sql_log_bin=0后执行的事务不会生成binlog 事件,也不会被记录到gtid_executed中。执行RESET MASTER可以将该变量置空。gtid_purgedbinlog不可能永远驻留在服务上,需要定期进行清理(通过expire_logs_days可以控制定期清理间隔),否则迟早它会把磁盘用尽。gtid_purged用于记录已经被清除了的binlog事务集合,它是gtid_executed的子集。只有gtid_executed为空时才能手动设置该变量,此时会同时更新gtid_executed为和gtid_purged相同的值。gtid_executed为空意味着要么之前没有启动过基于GTID的复制,要么执行过RESET MASTER。执行RESET MASTER时同样也会把gtid_purged置空,即始终保持gtid_purged是gtid_executed的子集。gtid_next会话级变量,指示如何产生下一个GTID。可能的取值如下:1)AUTOMATIC:自动生成下一个GTID,实现上是分配一个当前实例上尚未执行过的序号最小的GTID。2)ANONYMOUS:设置后执行事务不会产生GTID。3)显式指定的GTID:可以指定任意形式合法的GTID值,但不能是当前gtid_executed中的已经包含的GTID,否则,下次执行事务时会报错。这些变量可以通过show命令查看,比如:如何产生GTIDGTID的生成受gtid_next控制。 在Master上,gtid_next是默认的AUTOMATIC,即在每次事务提交时自动生成新的GTID。它从当前已执行的GTID集合(即gtid_executed)中,找一个大于0的未使用的最小值作为下个事务GTID。同时在binlog的实际的更新事务事件前面插入一条set gtid_next事件。以下是一条insert语句生成的binlog记录:在Slave上回放主库的binlog时,先执行set gtid_next ...,然后再执行真正的insert语句,确保在主和备上这条insert对应于相同的GTID。一般情况下,GTID集合是连续的,但使用多线程复制(MTS)以及通过gtid_next进行人工干预时会导致gtid空洞。比如下面这样:继续执行事务,MySQL会分配一个最小的未使用GTID,也就是从出现空洞的地方分配GTID,最终会把空洞填上。这意味着严格来说我们即不能假设GTID集合是连续的,也不能假定GTID序号大的事务在GTID序号小的事务之后执行,事务的顺序应由事务记录在binlog中的先后顺序决定。GTID的持久化GTID相关的信息存储在binlog文件中,为此MySQL5.6新增了下面2个binlog事件。Previous_gtids_log_event在每个binlog文件的开头部分,记录在该binlog文件之前已执行的GTID集合。Gtid_log_event即前面看到的set gtid_next ...,它出现在每个事务的前面,表明下一个事务的gtid。示例如下:MySQL服务器启动时,通过读binlog文件,初始化gtid_executed和gtid_purged,使它们的值能和上次MySQL运行时一致。gtid_executed被设置为最新的binlog文件中Previous_gtids_log_event和所有Gtid_log_event的并集。gtid_purged为最老的binlog文件中Previous_gtids_log_event。由于这两个重要的变量值记录在binlog中,所以开启gtid_mode时必须同时在主库上开启log_bin在备库上开启log_slave_updates。但是,在MySQL5.7中没有这个限制。MySQL5.7中,新增加一个系统表mysql.gtid_executed用于持久化已执行的GTID集合。当主库上没有开启log_bin或在备库上没有开启log_slave_updates时,mysql.gtid_executed会跟用户事务一起每次更新。否则只在binlog日志发生rotation时更新mysql.gtid_executed。如何配置基于GTID的复制MySQL服务器的my.cnf配置文件中增加GTID相关的参数log_bin= /mysql/binlog/mysql_binlog_slave_updates= truegtid_mode= ONenforce_gtid_consistency= truerelay_log_info_repository = TABLErelay_log_recovery= ON然后在Slave上指定MASTER_AUTO_POSITION = 1执行CHANGE MASTER TO即可。比如:CHANGE MASTER TO MASTER_HOST=‘node1‘,MASTER_USER=‘repl‘,MASTER_PASSWORD=‘repl‘,MASTER_AUTO_POSITION=1;基于GTID的复制如何工作在MASTER_AUTO_POSITION = 1的情况下 ,MySQL会使用COM_BINLOG_DUMP_GTID协议进行复制。过程如下:备库发起复制连接时,将自己的已接受和已执行的gtids的并集(后面称为slave_gtid_executed)发送给主库。即下面的集合:UNION(@@global.gtid_executed, Retrieved_gtid_set - last_received_GTID)主库将自己的gtid_executed与slave_gtid_executed的差集的binlog发送给Slave。主库的binlog dump过程如下:检查slave_gtid_executed是否是主库gtid_executed的子集,如否那么主备数据可能不一致,报错。检查主库的purged_executed是否是slave_gtid_executed的子集,如否代表缺失备库需要的binlog,报错从最后一个Binlog开始扫描,获取文件头部的PREVIOUS_GTIDS_LOG_EVENT,如果它是slave_gtid_executed的子集,则这是需要发送给Slave的第一个binlog文件,否则继续向前扫描。从第3步找到的binlog文件的开头读取binlog记录,判断binlog记录是否已被包含在slave_gtid_executed中,如果已包含跳过不发送。从上面的过程可知,在指定MASTER_AUTO_POSITION = 1时,Master发送哪些binlog记录给Slave,取决于Slave的gtid_executed和Retrieved_Gtid_Set以及Master的gtid_executed,和relay_log_info以及master_log_info中保存的复制位点没有关系。如何修复复制错误在基于GTID的复制拓扑中,要想修复Slave的SQL线程错误,过去的SQL_SLAVE_SKIP_COUNTER方式不再适用。需要通过设置gtid_next或gtid_purged完成,当然前提是已经确保主从数据一致,仅仅需要跳过复制错误让复制继续下去。比如下面的场景:在从库上创建表tb1mysql> set sql_log_bin=0;Query OK, 0 rows affected (0.00 sec)mysql> create table tb1(id int primary key,c1 int);Query OK, 0 rows affected (1.06 sec)mysql> set sql_log_bin=1;Query OK, 0 rows affected (0.00 sec)在主库上创建表tb1:mysql> create table tb1(id int primary key,c1 int);Query OK, 0 rows affected (1.06 sec)由于从库上这个表已经存在,从库的复制SQL线程出错停止。上面的输出可以知道,从库已经执行过的事务是‘e10c75be-5c1b-11e6-ab7c-000c296078ae:1-5‘,执行出错的事务是‘e10c75be-5c1b-11e6-ab7c-000c296078ae:6‘,当前主备的数据其实是一致的,可以通过设置gtid_next跳过这个出错的事务。在从库上执行以下SQL:mysql> set gtid_next=‘e10c75be-5c1b-11e6-ab7c-000c296078ae:6‘;Query OK, 0 rows affected (0.00 sec)mysql> begin;Query OK, 0 rows affected (0.00 sec)mysql> commit;Query OK, 0 rows affected (0.00 sec)mysql> set gtid_next=‘AUTOMATIC‘;Query OK, 0 rows affected (0.00 sec)mysql> start slave;Query OK, 0 rows affected (0.02 sec)设置gtid_next的方法一次只能跳过一个事务,要批量的跳过事务可以通过设置gtid_purged完成。假设下面的场景:主库上已执行的事务从库上已执行的事务假设经过修复从库已经和主库的数据一致了,但由于复制错误Slave的SQL线程依然处于停止状态。现在可以通过把从库的gtid_purged设置为和主库的gtid_executed一样跳过不一致的GTID使复制继续下去,步骤如下。在从库上执行此时从库的Executed_Gtid_Set已经包含了主库上‘1-10‘的事务,再开启复制会从后面的事务开始执行,就不会出错了。mysql> start slave;Query OK, 0 rows affected (0.01 sec)使用gtid_next和gtid_purged修复复制错误的前提是,跳过那些事务后仍可以确保主备数据一致。如果做不到,就要考虑pt-table-sync或者拉备份的方式了。GTID与备份恢复在做备份恢复的时候,有时需要恢复出来的MySQL实例可以作为Slave连上原来的主库继续复制,这就要求从备份恢复出来的MySQL实例拥有和数据一致的gtid_executed值。这也是通过设置gtid_purged实现的,下面看下mysqldump做备份的例子。1、通过mysqldump进行备份通过mysqldump做一个全量备份:[root@node1 ~]# mysqldump --all-databases --single-transaction --routines --events --host=127.0.0.1 --port=3306 --user=root > dump.sql生成的dump.sql文件里包含了设置gtid_purged的语句SET @MYSQLDUMP_TEMP_LOG_BIN = @@SESSION.SQL_LOG_BIN;SET @@SESSION.SQL_LOG_BIN= 0;...SET @@GLOBAL.GTID_PURGED=‘e10c75be-5c1b-11e6-ab7c-000c296078ae:1-10‘;...SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;恢复数据前需要先通过reset master清空gtid_executed变量[root@node2 ~]# mysql -h127.1 -e ‘reset master‘[root@node2 ~]# mysql -h127.1 <dump.sql否则执行设置GTID_PURGED的SQL时会报下面的错误ERROR 1840 (HY000) at line 24: @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty.此时恢复出的MySQL实例的GTID_EXECUTED和备份时点一致:由于恢复出的MySQL实例已经被设置了正确的GTID_EXECUTED,以master_auto_postion = 1的方式CHANGE MASTER到原来的主节点即可开始复制。CHANGE MASTER TO MASTER_HOST=‘node1‘, MASTER_USER=‘repl‘, MASTER_PASSWORD=‘repl‘, MASTER_AUTO_POSITION = 1如果不希望备份文件中生成设置GTID_PURGED的SQL,可以给mysqldump传入--set-gtid-purged=OFF关闭。2、通过Xtrabackup进行备份相比mysqldump,Xtrabackup是效率更高并且被广泛使用的备份方式。使用Xtrabackup进行备份的举例如下。通过Xtrabackup创一个全量备份(可以在Slave上创建备份,以避免对主库的性能冲击)innobackupex --defaults-file=/etc/my.cnf --host=127.1 --user=root --password=mysql --no-timestamp --safe-slave-backup --slave-info /mysql/bak应用日志innobackupex --apply-log /mysql/bak查看备份目录中的xtrabackup_binlog_info文件可以找到备份时已经执行过的gtids[root@node2 ~]# cat /mysql/bak/xtrabackup_binlog_infomysql_bin.000001191e10c75be-5c1b-11e6-ab7c-000c296078ae:1-10由于备份时添加了”--slave-info”选项并且从Slave节点拉取的备份,所以会生成xtrabackup_slave_info文件,也可以从这个文件里查找建立复制的SQL语句。[root@node2 ~]# cat /mysql/bak/xtrabackup_slave_infoSET GLOBAL gtid_purged=‘e10c75be-5c1b-11e6-ab7c-000c296078ae:1-10‘;CHANGE MASTER TO MASTER_AUTO_POSITION=1将备份文件传送到新的节点node3的/mysql/bak目录并恢复(如果直接把备份传输到数据目录了,这一步可以省略)。[root@node3 ~]# innobackupex --defaults-file=/etc/my.cnf --copy-back /mysql/bak启动MySQL。[root@node3 ~]# mysqld --defaults-file=/home/mysql/etc/my.cnf --skip-slave-start &如果是从Slave拉的备份,一定不能直接开启Slave复制,这时的gtid_executed是错误的。需要手动设置gtid_purged后再start slaveMASTER_HOST=‘node1‘,MASTER_USER=‘repl‘,MASTER_PASSWORD=‘repl‘,MASTER_AUTO_POSITION=1;start slave;GTID与MHAMHA是被广泛使用MySQL HA组件,MHA 0.56以后支持基于GTID的复制。 MHA在failover时会自动判断是否是GTID based failover,需要满足下面3个条件即为GTID based failover所有节点gtid_mode=1所有节点Executed_Gtid_Set不为空至少一个节点Auto_Position=1和之前的基于binlog文件位置的复制相比,基于GTID复制下,MHA在故障切换时的变化主要如下:基于binlog文件位置的复制在Master宕机后会尝试从Master上拷贝binlog日志进行补偿如果候选Master不拥有最新的relay log,会从拥有最新relay log的Slave上生成差异的binlog传送到候选Master并实施补偿新Master的日志补偿完成后,同样采用应用差异binlog的方式将其它Slave和新Master同步后再change master到新Master基于GTID的复制如果候选Master不拥有最新的relay log,让候选Master连上拥有最新relay log的Salve进行补偿。尝试从binlog server上拉取缺失的binlog并应用新Master的数据同步到最新后,让其它的Slave连上新Master并等待数据完成同步。并且可以给masterha_master_switch传入--wait_until_gtid_in_sync=1参数使其不等其它Slave完成数据同步,以加快切换速度。GTID模式下MHA不会尝试从旧Master上拷贝binlog日志进行补偿,所以在MySQL进程crash而OS仍然健康的情况下,应尽量不要做主备切换而是原地重启MySQL,除非有其2023-08-05 23:15:151
大神帮帮忙,JDBC的操作老是报这个错误 改了半天不知道问题出在哪里, 新电脑刚安装的sql2008和MyEclipse10
确保你的电脑SSL服务已经开启2023-08-05 23:15:471
Oracle数据库分区表操作方法
在大型的企业应用或企业级的数据库应用中 要处理的数据量通常可以达到几十到几百GB 有的甚至可以到TB级 虽然存储介质和数据处理技术的发展也很快 但是仍然不能满足用户的需求 为了使用户的大量的数据在读写操作和查询中速度更快 Oracle提供了对表和索引进行分区的技术 以改善大型应用系统的性能 使用分区的优点 ·增强可用性 如果表的某个分区出现故障 表在其他分区的数据仍然可用 ·维护方便 如果表的某个分区出现故障 需要修复数据 只修复该分区即可 ·均衡I/O 可以把不同的分区映射到磁盘以平衡I/O 改善整个系统性能 ·改善查询性能 对分区对象的查询可以仅搜索自己关心的分区 提高检索速度 Oracle数据库提供对表或索引的分区方法有三种 ·范围分区 ·Hash分区(散列分区) ·复合分区 下面将以实例的方式分别对这三种分区方法来说明分区表的使用 为了测试方便 我们先建三个表空间 以下为引用的内容 create tablespace dinya_space datafile /test/demo/oracle/demodata/dinya dnf size M create tablespace dinya_space datafile /test/demo/oracle/demodata/dinya dnf size M create tablespace dinya_space datafile /test/demo/oracle/demodata/dinya dnf size M 分区表的创建 范围分区 范围分区就是对数据表中的某个值的范围进行分区 根据某个值的范围 决定将该数据存储在哪个分区上 如根据序号分区 根据业务记录的创建日期进行分区等 需求描述 有一个物料交易表 表名 material_transactions 该表将来可能有千万级的数据记录数 要求在建该表的时候使用分区表 这时候我们可以使用序号分区三个区 每个区中预计存储三千万的数据 也可以使用日期分区 如每五年的数据存储在一个分区上 根据交易记录的序号分区建表 以下为引用的内容 SQL> create table dinya_test ( transaction_id number primary key item_id number( ) not null item_description varchar ( ) transaction_date date not null ) partition by range (transaction_id) ( partition part_ values less than( ) tablespace dinya_space partition part_ values less than( ) tablespace dinya_space partition part_ values less than(maxvalue) tablespace dinya_space ); Table created 建表成功 根据交易的序号 交易ID在三千万以下的记录将存储在第一个表空间dinya_space 中 分区名为:par_ 在三千万到六千万之间的记录存储在第二个表空间 dinya_space 中 分区名为 par_ 而交易ID在六千万以上的记录存储在第三个表空间dinya_space 中 分区名为par_ 根据交易日期分区建表 以下为引用的内容 SQL> create table dinya_test ( transaction_id number primary key item_id number( ) not null item_description varchar ( ) transaction_date date not null ) partition by range (transaction_date) ( partition part_ values less than(to_date( yyyy mm dd )) tablespace dinya_space partition part_ values less than(to_date( yyyy mm dd )) tablespace dinya_space partition part_ values less than(maxvalue) tablespace dinya_space ); Table created 这样我们就分别建了以交易序号和交易日期来分区的分区表 每次插入数据的时候 系统将根据指定的字段的值来自动将记录存储到制定的分区(表空间)中 当然 我们还可以根据需求 使用两个字段的范围分布来分区 如partition by range ( transaction_id transaction_date) 分区条件中的值也做相应的改变 请读者自行测试 Hash分区(散列分区) 散列分区为通过指定分区编号来均匀分布数据的一种分区类型 因为通过在I/O设备上进行散列分区 使得这些分区大小一致 如将物料交易表的数据根据交易ID散列地存放在指定的三个表空间中 以下为引用的内容 SQL> create table dinya_test ( transaction_id number primary key item_id number( ) not null item_description varchar ( ) transaction_date date ) partition by hash(transaction_id) ( partition part_ tablespace dinya_space partition part_ tablespace dinya_space partition part_ tablespace dinya_space ); Table created 建表成功 此时插入数据 系统将按transaction_id将记录散列地插入三个分区中 这里也就是三个不同的表空间中 复合分区 有时候我们需要根据范围分区后 每个分区内的数据再散列地分布在几个表空间中 这样我们就要使用复合分区 复合分区是先使用范围分区 然后在每个分区内再使用散列分区的一种分区方法 如将物料交易的记录按时间分区 然后每个分区中的数据分三个子分区 将数据散列地存储在三个指定的表空间中 以下为引用的内容 SQL> create table dinya_test ( transaction_id number primary key item_id number( ) not null item_description varchar ( ) transaction_date date ) partition by range(transaction_date)subpartition by hash(transaction_id) subpartitions store in (dinya_space dinya_space dinya_space ) ( partition part_ values less than(to_date( yyyy mm dd )) partition part_ values less than(to_date( yyyy mm dd )) partition part_ values less than(maxvalue) ); Table created 该例中 先是根据交易日期进行范围分区 然后根据交易的ID将记录散列地存储在三个表空间中 分区表操作 以上了解了三种分区表的建表方法 下面将使用实际的数据并针对按日期的范围分区来测试分区表的数据记录的操作 插入记录 以下为引用的内容 SQL> insert into dinya_test values( BOOKS sysdate); row created SQL> insert into dinya_test values( BOOKS sysdate+ ); row created SQL> insert into dinya_test values( BOOKS to_date( yyyy mm dd )); row created SQL> insert into dinya_test values( BOOKS to_date( yyyy mm dd )); row created SQL> insert into dinya_test values( BOOKS to_date( yyyy mm dd )); row created SQL> insert into dinya_test values( BOOKS to_date( yyyy mm dd )); row created SQL> mit; Commit plete SQL> 按上面的建表结果 年前的数据将存储在第一个分区part_ 上 而 年到 年的交易数据将存储在第二个分区part_ 上 年以后的记录存储在第三个分区part_ 上 查询分区表记录 以下为引用的内容 SQL> select * from dinya_test partition(part_ ); TRANSACTION_ID ITEM_ID ITEM_DESCRIPTION TRANSACTION_DATE BOOKS : : BOOKS : : SQL> SQL> select * from dinya_test partition(part_ ); TRANSACTION_ID ITEM_ID ITEM_DESCRIPTION TRANSACTION_DATE BOOKS BOOKS SQL> SQL> select * from dinya_test partition(part_ ); TRANSACTION_ID ITEM_ID ITEM_DESCRIPTION TRANSACTION_DATE BOOKS BOOKS SQL> 从查询的结果可以看出 插入的数据已经根据交易时间范围存储在不同的分区中 这里是指定了分区的查询 当然也可以不指定分区 直接执行select * from dinya_test查询全部记录 在也检索的数据量很大的时候 指定分区会大大提高检索速度 更新分区表的记录 以下为引用的内容 SQL> update dinya_test partition(part_ ) t set em_description= DESK where t transaction_id= ; row updated SQL> mit; Commit plete SQL> 这里将第一个分区中的交易ID= 的记录中的item_description字段更新为 DESK 可以看到已经成功更新了一条记录 但是当更新的时候指定了分区 而根据查询的记录不在该分区中时 将不会更新数据 请看下面的例子 以下为引用的内容 SQL> update dinya_test partition(part_ ) t set em_description= DESK where t transaction_id= ; rows updated SQL> mit; Commit plete SQL> 指定了在第一个分区中更新记录 但是条件中限制交易ID为 而查询全表 交易ID为 的记录在第三个分区中 这样该条语句将不会更新记录 删除分区表记录 以下为引用的内容 SQL> delete from dinya_test partition(part_ ) t where t transaction_id= ; row deleted SQL> mit; Commit plete SQL> 上面例子删除了第二个分区part_ 中的交易记录ID为 的一条记录 和更新数据相同 如果指定了分区 而条件中的数据又不在该分区中时 将不会删除任何数据 分区表索引的使用 分区表和一般表一样可以建立索引 分区表可以创建局部索引和全局索引 当分区中出现许多事务并且要保证所有分区中的数据记录的唯一性时采用全局索引 局部索引分区的建立 以下为引用的内容 SQL> create index dinya_idx_t on dinya_test(item_id) local ( partition idx_ tablespace dinya_space partition idx_ tablespace dinya_space partition idx_ tablespace dinya_space ); Index created SQL> 看查询的执行计划 从下面的执行计划可以看出 系统已经使用了索引 以下为引用的内容 SQL> select * from dinya_test partition(part_ ) t where em_id= ; Execution Plan SELECT STATEMENT Optimizer=CHOOSE (Cost= Card= Bytes= ) TABLE ACCESS (BY LOCAL INDEX ROWID) OF DINYA_TEST (Cost= Card= Bytes= ) INDEX (RANGE SCAN) OF DINYA_IDX_T (NON UNIQUE) (Cost= Card= ) Statistics recursive calls db block gets consistent gets physical reads redo size bytes sent via SQL*Net to client bytes received via SQL*Net from client SQL*Net roundtrips to/from client sorts (memory) sorts (disk) rows processed SQL> 全局索引分区的建立 全局索引建立时global 子句允许指定索引的范围值 这个范围值为索引字段的范围值 以下为引用的内容 SQL> create index dinya_idx_t on dinya_test(item_id) global partition by range(item_id) ( partition idx_ values less than ( ) tablespace dinya_space partition idx_ values less than ( ) tablespace dinya_space partition idx_ values less than (maxvalue) tablespace dinya_space ); Index created SQL> 本例中对表的item_id字段建立索引分区 当然也可以不指定索引分区名直接对整个表建立索引 如 以下为引用的内容 SQL> create index dinya_idx_t on dinya_test(item_id); Index created SQL> 同样的 对全局索引根据执行计划可以看出索引已经可以使用 以下为引用的内容 SQL> select * from dinya_test t where em_id= ; Execution Plan SELECT STATEMENT Optimizer=CHOOSE (Cost= Card= Bytes= ) TABLE ACCESS (BY GLOBAL INDEX ROWID) OF DINYA_TEST (Cost = Card= Bytes= ) INDEX (RANGE SCAN) OF DINYA_IDX_T (NON UNIQUE) (Cost= Card= ) Statistics recursive calls db block gets consistent gets physical reads redo size bytes sent via SQL*Net to client bytes received via SQL*Net from client SQL*Net roundtrips to/from client sorts (memory) sorts (disk) rows processed SQL> 分区表的维护 了解了分区表的建立 索引的建立 表和索引的使用后 在应用的还要经常对分区进行维护和管理 日常维护和管理的内容包括 增加一个分区 合并一个分区及删除分区等等 下面以范围分区为例说明增加 合并 删除分区的一般操作 增加一个分区: 以下为引用的内容 SQL> alter table dinya_test add partition part_ values less than(to_date( yyyy mm dd )) tablespace dinya_spa ce ; Table altered SQL> 增加一个分区的时候 增加的分区的条件必须大于现有分区的最大值 否则系统将提示ORA partition bound must collate higher than that of the last partition 错误 合并一个分区 以下为引用的内容 SQL> alter table dinya_test merge partitions part_ part_ into partition part_ ; Table altered SQL> 在本例中将原有的表的part_ 分区和part_ 分区进行了合并 合并后的分区为part_ 如果在合并的时候把合并后的分区定为part_ 的时候 系统将提示ORA cannot reuse lower bound partition as resulting partition 错误 删除分区 以下为引用的内容 SQL> alter table dinya_test drop partition part_ ; Table altered SQL> 删除分区表的一个分区后 查询该表的数据时显示 该分区中的数据已全部丢失 所以执行删除分区动作时要慎重 确保先备份数据后再执行 或将分区合并 总结 lishixinzhi/Article/program/Oracle/201311/173292023-08-05 23:15:541
如何将enom域名转到godaddy呢?
如果有转移码就可以转到godaddy2023-08-05 23:16:092
postgresql如何维护WAL日志/归档日志
. 参数max_wal_size/min_wal_size 9.5以前: (2 + checkpoint_completion_target) * checkpoint_segments + 1 9.5:PostgreSQL 9.5 将废弃checkpoint_segments 参数, 并引入max_wal_size 和 min_wal_size 参数, 通过max_wal_size和checkpoint_completion_target 参数来控制产生多少个XLOG后触发检查点, 通过min_wal_size和max_wal_size参数来控制哪些XLOG可以循环使用。2. 参数wal_keep_segments 在流复制的环境中。使用流复制建好备库,如果备库由于某些原因接收日志较慢。导致备库还未接收到。就被覆盖了。导致主备无法同步。这个需要重建备库。 避免这种情况提供了该参数。每个日志文件大小16M。如果参数设置64. 占用大概64×16=1GB的空间。根据实际环境设置。3. pg_resetxlog 在前面参数设置合理的话。是用不到pg_resetxlog命令。 使用案例参考: https://my.oschina.net/Kenyon/blog/101432[postgres@postgres128 ~]$ pg_resetxlog -?pg_resetxlog resets the PostgreSQL transaction log.Usage: pg_resetxlog [OPTION]... DATADIROptions: -c XID,XID set oldest and newest transactions bearing commit timestamp (zero in either value means no change) [-D] DATADIR data directory -e XIDEPOCH set next transaction ID epoch -f force update to be done -l XLOGFILE force minimum WAL starting location for new transaction log -m MXID,MXID set next and oldest multitransaction ID -n no update, just show what would be done (for testing) -o OID set next OID -O OFFSET set next multitransaction offset -V, --version output version information, then exit -x XID set next transaction ID -?, --help show this help, then exitReport bugs to <pgsql-bugs@postgresql.org>. 归档日志维护1. pg_archivecleanup清理归档日志。[postgres@postgres128 ~]$ pg_archivecleanup -?pg_archivecleanup removes older WAL files from PostgreSQL archives.Usage: pg_archivecleanup [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILEOptions: -d generate debug output (verbose mode) -n dry run, show the names of the files that would be removed -V, --version output version information, then exit -x EXT clean up files if they have this extension -?, --help show this help, then exitFor use as archive_cleanup_command in recovery.conf when standby_mode = on: archive_cleanup_command = ‘pg_archivecleanup [OPTION]... ARCHIVELOCATION %r‘e.g. archive_cleanup_command = ‘pg_archivecleanup /mnt/server/archiverdir %r‘Or for use as a standalone archive cleaner:e.g. pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup1.1 当主库不断把WAL日志拷贝到备库。这个时候需要清理。在recovery.conf可以配置 e.g. archive_cleanup_command = ‘pg_archivecleanup /mnt/server/archiverdir %r‘1.2 可以收到执行命令。e.g. pg_archivecleanup /home/postgres/arch/ 000000010000000000000009在归档目录/home/postgres/arch/ 把000000010000000000000009之前的日志都清理。2. pg_rman备份参考博客 http://www.cnblogs.com/lottu/p/7490615.html在pg_rman备份保留策略中。在每天都备份。可以清理归档日志。对流复制环境中。备份一般是在备库。可以把归档日志传送到备库中。 --keep-arclog-files=NUM keep NUM of archived WAL --keep-arclog-days=DAY keep archived WAL modified in DAY dayse.g 保留归档日志个数10。或者保留10天内的归档日志。 KEEP_ARCLOG_FILES = 10 KEEP_ARCLOG_DAYS = 10 在备份信息中会产生以下信息。INFO: start deleting old archived WAL files from ARCLOG_PATH (keep files = 10, keep days = 10)postgresql如何维护WAL日志/归档日志标签:-oarchtargenbspnimamp16进制segment如何2023-08-05 23:16:161
pt-query-digest 可以分析general log中查询次数最多的sql语句吗
定期分析sqlserver日志是DBA很重要的任务,那如何才能查看sqlserver日志呢?在SQLServer7.0和SQLServer2000中,可以用下面的命令查看:DBCClog({dbid|dbname},[,type={0|1|2|3|4}]) 参数: Dbidordbname-任一数据库的ID或名字 type-输出结果的类型: 0-最少信息(operation,context,transactionid) 1-信息(plusflags,tags,rowlength) 2-非常详细的信息(plusobjectname,indexname,pageid,slotid) 3-每种操作的全部信息 4-每种操作的全部信息加上该事务的16进制信息 默认type=0 要查看MSATER数据库的事务日志可以用以下命令:DBCClog(master)释放日志空间1.清空日志 DUMPTRANSACTION库名WITHNO_LOG2.截断事务日志: BACKUPLOG数据库名WITHNO_LOG3.收缩数据库文件(如果不压缩,数据库的文件不会减小 企业管理器--右键你要压缩的数据库--所有任务--收缩数据库--收缩文件 --选择日志文件--在收缩方式里选择收缩至XXM,这里会给出一个允许收缩到的最小M数,直接输入这个数,确定就可以了 --选择数据文件--在收缩方式里选择收缩至XXM,这里会给出一个允许收缩到的最小M数,直接输入这个数,确定就可以了 也可以用SQL语句来完成 --收缩数据库 DBCCSHRINKDATABASE(客户资料) --收缩指定数据文件,1是文件号,可以通过这个语句查询到:select*fromsysfiles DBCCSHRINKFILE(1)4.为了最大化的缩小日志文件(如果是sql7.0,这步只能在查询分析器中进行) a.分离数据库: 企业管理器--服务器--数据库--右键--分离数据库 b.在我的电脑中删除LOG文件 c.附加数据库: 企业管理器--服务器--数据库--右键--附加数据库 此法将生成新的LOG,大小只有500多K 或用代码: 下面的示例分离pubs,然后将pubs中的一个文件附加到当前服务器。 a.分离 EXECsp_detach_db@dbname="pubs" b.删除日志文件 c.再附加 EXECsp_attach_single_file_db@dbname="pubs", @physname="c:ProgramFilesMicrosoftSQLServerMSSQLDatapubs.mdf"5.为了以后能自动收缩,做如下设置: 企业管理器--服务器--右键数据库--属性--选项--选择"自动收缩" --SQL语句设置方式: EXECsp_dboption"数据库名","autoshrink","TRUE"6.如果想以后不让它日志增长得太大 企业管理器--服务器--右键数据库--属性--事务日志 --将文件增长限制为xM(x是你允许的最大数据文件大小) --SQL语句的设置方式: alterdatabase数据库名modifyfile(name=逻辑文件名,maxsize=20)特别注意: 请按步骤进行,未进行前面的步骤,请不要做后面的步骤 否则可能损坏你的数据库. 一般不建议做第4,6两步 第4步不安全,有可能损坏数据库或丢失数据 第6步如果日志达到上限,则以后的数据库处理会失败,在清理日志后才能恢复.另外提供一种更简单的方法,建议大家使用。更简单的方法:1。右建数据库属性窗口--故障还原模型--设为简单2。右建数据库所有任务--收缩数据库3。右建数据库属性窗口--故障还原模型--设为大容量日志记录2023-08-05 23:16:241
Openvidu Server 的WebRTC通讯实现 IV
a. 在openvidu中,一个激活的会议由kurentoSession实例表示。当创参会者加入会议时,openvidu会创建一个kurentoSession实例。 b. 在kurento服务器上,一个会议由一个pipeLine 和N N个mediaEndpoint表示。N表是参会方数量,每一个参会方会创建一个发布媒体用的MediaElement和(n-1)个订阅其它媒体流用的MediaElement,它们被编排入一个PepleLine中, 形成N N的连接。 所以,当第一个用户加入会议室时,系统会在Openvidu上创建一个KurentoSession实例,同时在Kurento上创建一个pipleLine, KurentoSession 实例引用了这个pipepline. N个用户会有N个kurentoSession, 但只有一个pipleline。PipleLine的描述是在Kurento Client包里。 管理器中另外一个重要的是sessionManager,session代表的是会议,所以sessionMananger 实际就是所有具体会议的管理. 在io.openvidu.server.core包下的SessionManager只是一个虚类,它声明了一些会议的操作方法: 这些方法都和会议有关, 可以发现,上面的功能通常对应我们音视频软件进入会议室的功能。 开openvidu中,它的具体的实现是KurentoSessionManager,它会在server启动的时候初始化。 在III中说了,sessionid 代表的会议号,创建会议的时候会创建一个sessionNotActive(Session类)对象,代表的是还未正式使用的会议,当第一个用户首次加入的时候,才会正式使用这个会议,KurentoSessionManager的joinRoom方法描述了相关的逻辑。 与sessionNotActive不同,一个开始使用的会议用KurentoSession来表示(继承自Session),首次加入会议, 需要创建这个Ksession, 它会指定一个具体的Kurrento Server,ksession的创建需要指定具体kms,用来表示在具体哪个KMS创建会议。社区版实际上只有一个KMS,但在实现上如下图, 已经默认使用获取最小负载的方式获得kms。 sessionManager对外提供会议操作功能的统一入口,每个会议对应的kurentoSession负责实际与kurento server的通信,来完具体的会议操作。所以在kurentoSession中我们可以看到相类似的会议功能定义: 上图是一个包含有浏览器、application 、 openvidu server, 、kurento server 等在内的一个逻辑通讯图。 浏览器端加载会议应用程序,通过http协议与application server通信,完成业务请求和获取用于会议的token和sessionID. applicaiton server只负责业务请求,它通过与openvidu server通信来生成浏览器客户端加入会议需要的token和sessionID信息。 浏览器获取token和sessionid后,与openvidu建立websocket连接,它将openvidu作为webrtc中的singal server,与openvidu通信,完成建立webrtc所需要的singal通信。 与webrtc中描述的P2P通讯不同,kurento server 充当代理,与每一个参与方建立p2p连接,通过创建pipleline和编排media endpoint完成多方的通讯。 但是Kurento Server与任意参与方建立的通讯仍旧是P2P通讯。所以,浏览器会与kurento server建立webrtc连接。 他们的通讯默认是RTP over UPD, 也可以是RTP over TCP。 openvidu与kurento也是通过websocket连接进行通讯的,与kurento的通信包含两个方面: a. 作为控制方,创建pipleline,根据加入的用户创建media endpoint, 并编排他们。 b。 作为信号服务器, 与Kurento进行webrtc连接时需要的信号通讯:例如发送sdp, icecandidate,sdp响应等,由于kurento并不是浏览器端,Sdp answser的创建,也是由openvidu完成的。 Openvidu与Kurento之间的通讯编码使用json RPC方式。 kurento 提供了client 包,方便opnvidu 实现rpc调用。 4.1 PipleLine org.kurento.client包里包含一个pipleLIne类,它代表kurento server上的media pipleLine元素; 前面已经提到,一个会议对应一个kurencto pipleLine。而在openvidu中kurentoSession代表一个会议,它包含有一个pipleliene属性: private MediaPipeline pipeline; 在首个用户加入会议的时候,会创建PipleLine实例: 查看createPipeline方法可以看到,pipleLine使用kurentoclient来创建的。 kms.getKurentoClient().createMediaPipeline(...) PipleLine创建好一个,将作为会议的具体Rpc对象负责其它对象的创建和方法调用。 4.2 MediaEndpoint,publisherEndpoint、SubscriberEndpoint openvidu里定义了一个个类:MediaEndpoint。 它对应的是kurento server上MediaElement的抽象,下图是Kurento上的元素概念: 在MediaEndpoint类中,定义了三个endpoint属性,代表三种连接类型: ··· ··· WebRtcEndpoint 、RtpEndpoint 、PlayerEndpoint 这三个类来自kurent client包,代表JSonrpc的客户端类,在上图的kurento元素中能够找到对应的元素。 MediaEndpoint对三个类做了风中,使用endpointType来表示当前是那种类型(也就是哪个引用有值)。它有两个子类publisherEndpoint和SubscriberEndpoint,分别表示一个用于publish的mediaElement 和用于subscribe的mediaElement 。 在前文提到, openvidu的会议在kurento server上表示N*N 模型的media element关系, Server会为每一个参会者创建一个用于音视频发布的mediaElement 和(n-1)个用于订阅其它用户发布的音视频的media element,publisherEndpoint和SubscriberEndpoint对应的就是这个概念。 无论publisherEndpoint和SubscriberEndpoint是WebRtcEndpoint 、 RtpEndpoint,PlayerEndpoint中的哪个类型,它们封装的rpc对象都由 pipeline创建。 4.3 KurentoParticipant openvidu中的KurentoParticipant类代表的是参会方(不同于我们平时理解的用户),每个用户加入会议后才会创建KurentoParticipant,在 "3.Openvidu Server与WebRTC的通信" 的示例图中表征的是一个浏览器与Kurento server的连接。一个用户可以打开多个浏览器页面,每个加入会议的页面实际上都代表一个KurentoParticipant。 KurentoParticipant没有具体的JsonPRC对象,相反它拥有一个PublisherEndpoint和 一组subscribers,它们在kurento server刚好表示一个会议参与方: 由于KurentoParticipant代表的是会议的参会方,这个类中定义了几乎所有与publisher和subscribers 有关的操作: 4.4 KurentoSession KurentoSession 代表的是一个会议,在kurento上对应的是pipeline mediaElement,但它不属于JsonRPC对象,它对pipeline mediaElement的操作是由PipleLine Jsonrpc对象来完成的,所以它包含由pipeline属性: 这个类中定义了很多会议操作的方法: 浏览器客户端在创建连接获取token和session时,并不会直接创建KurentoSession,默认的只会创建一个session对象,并把它放在sessionNotActive组里。当用户Join会议的时候(调用 KurentoSessionManager.joinRoom(Participant participant, String sessionId, Integer transactionId) ),才会创建KurentoSession 实例。2023-08-05 23:16:311
固定资产中的业务类型如何与t-code 联系起来的?
1、如附图:我们公司使用f-92时,transaction type 默认就是210,我想让它该成其他的,通过 皮卡提供的默认的设置改动,却都改不了这个地方,所以我就很疑惑了,我做报表要区分去哪些 卖给客户,哪些是卖给关系企业,就无法通过这个地方来做了,只能通过客户的帐户组来区分 ....... 明白啦,你是利用贷方科目做报废标识的方法作的,那么就需要在IMG中的‘确定内部业务的 业务类型"下面配置缺省的、同客户过帐相关的业务类型,如在‘报废"中设置其他值。 但是,如果我理解没错的话,你的报表需求就是想区分销售业务对象的属性,那么本来就应该 从相关主数据中的账组等属性来判断,而业务类型只是反应资产交易类别,并非客户属性啊。 另,你在配ABZON时,由于此TCODE是46版本下的新事务(以前版本都是ABZO),你在对应的 ABZO下设置,当然不行。而你用的Retirement with revenue的ATI是AMBU(只看标识ID的头 4位),这个东东便是在报废相关的程序中调用的ATI,程序SAPLAMDP(ABZON事务代码所关联 的程序)下的关联子程序LAMBUCD0、LAFARCON等等,参见类似的标识声明语句... CONSTANTS: GC_AWTYP_AMBU LIKE RLAMBU-AWTYP ?VALUE "AMBU" 所以,这些缺省关联的TCODE需要一定的分析研究,才能确定对应的事务。2023-08-05 23:16:391
ectn是什么费用?办理花多少钱
ectn是电子货物跟踪单的费用,也叫电子货物跟踪号。根据刚果布通告编号 N°151 / CCC/DG 签发于15/04/2004 ,即日起所有运往刚果布港口(POINTE NOIRE黑角)或经由此港转往其他目的地的货物都必须申请ECTN货物跟踪单。否则将视为触犯刚果布的条例,并在目的港受到严厉惩罚。刚果布ECTN办理流程一,申请人提供申请表,COMMERCIAL INVOICE,提单副本或确认件或格式件,TI;二,收到上述材料后出正式报价单;三,申请人安排汇款;四,收到汇款后出证书草稿;五,申请人确认草稿;六,ZKTEST出具证书正本。2023-08-05 23:16:472
Trans ID在贸易中什么含义
P/O NO: PURCHASE ORDER NUMBER定单号码Trans ID:Transaction ID,交易识别符(交易流水号)..2023-08-05 23:17:431
paypal payment Transaction ID 是交易号还是我的paypal对应的邮箱
是Paypal方的订单交易号,方便Paypal系统查找金流详情的追踪号。2023-08-05 23:17:501
Original_partner_transaction_ID是什么意思?
原始合伙人交易号2023-08-05 23:18:051
SQLServer数据库怎么查看表的修改记录
可以尝试如下建议:1、可以使用默认的Log工具或者第三方的(比如:LiteSpeed)的工具。2、做Trace机制,下次出现问题可以溯源。3、一个简单的办法:--Step #1:USE DBNameGOSELECT [Transaction ID], Operation, Context, AllocUnitNameFROM fn_dblog(NULL, NULL) WHERE Operation = "LOP_DELETE_ROWS" and AllocUnitName= "dbo.Test.PK__Test__5F573DD6" -- 这里 "dbo.Test.PK__Test__5F573DD6"指表名的PK_Name -- 可以使用 SP_Pkeys SourceTableName 查到--Step #2:SELECT Operation, [Transaction ID], [Begin Time], [Transaction Name], [Transaction SID]FROM fn_dblog(NULL, NULL)WHERE [Transaction ID] ="0000:0005afba" -- 这里 "0000:0005afba" 指Step #1中的Transaction IDAND [Operation] = "LOP_BEGIN_XACT"--Step #3:USE MASTERGO SELECT SUSER_SNAME(0x01) "UserID" --这里"0000:0005afba" 值Step #2中的Transaction SID2023-08-05 23:18:151
postgresql怎么查看锁表
SELECTn.nspname as "Schema",c.relname as "Name",CASE c.relkind WHEN "r" THEN "table" WHEN "v" THEN "view" WHEN "i" THEN "index" WHEN "S" THEN "sequence" WHEN "s" THEN "special" END as "Type",r.rolname as "Owner"FROM pg_catalog.pg_class cJOIN pg_catalog.pg_roles r ON r.oid = c.relownerLEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespaceWHERE c.relkind IN ("v","")AND n.nspname = "pg_catalog"AND n.nspname !~ "^pg_toast"AND pg_catalog.pg_table_is_visible(c.oid)ORDER BY 1,2;查看当前活动的客户端连接数:SELECT count(*) FROM pg_stat_activity WHERE NOT procpid=pg_backend_pid();查询客户端连接的情况:SELECT procpid,waiting,current_timestamp - least(query_start,xact_start) AS runtime,substr(current_query,1,25) AS current_query FROM pg_stat_activity WHERE NOT procpid=pg_backend_pid();查看当前锁的一些信息:SELECTlocktype,virtualtransaction,transactionid,nspname,relname,mode,granted,cast(date_trunc("second",query_start) AS timestamp) AS query_start,substr(current_query,1,25) AS queryFROMpg_locksLEFT OUTER JOIN pg_class ON (pg_locks.relation = pg_class.oid)LEFT OUTER JOIN pg_namespace ON (pg_namespace.oid = pg_class.relnamespace),pg_stat_activityWHERENOT pg_locks.pid=pg_backend_pid() ANDpg_locks.pid=pg_stat_activity.procpid;查看持有锁的一些信息:SELECTlocked.pid AS locked_pid,locker.pid AS locker_pid,locked_act.usename AS locked_user,locker_act.usename AS locker_user,locked.virtualtransaction,locked.transactionid,locked.locktypeFROMpg_locks locked,pg_locks locker,pg_stat_activity locked_act,pg_stat_activity locker_actWHERElocker.granted=true ANDlocked.granted=false ANDlocked.pid=locked_act.procpid ANDlocker.pid=locker_act.procpid AND(locked.virtualtransaction=locker.virtualtransaction ORlocked.transactionid=locker.transactionid);还是查看锁的一些信息:SELECTlocked.pid AS locked_pid,locker.pid AS locker_pid,locked_act.usename AS locked_user,locker_act.usename AS locker_user,locked.virtualtransaction,locked.transactionid,relnameFROMpg_locks lockedLEFT OUTER JOIN pg_class ON (locked.relation = pg_class.oid),pg_locks locker,pg_stat_activity locked_act,pg_stat_activity locker_actWHERElocker.granted=true ANDlocked.granted=false ANDlocked.pid=locked_act.procpid ANDlocker.pid=locker_act.procpid ANDlocked.relation=locker.relation;查看当前库表和索引的的大小并排序显示前20条:SELECTnspname,relname,pg_size_pretty(pg_relation_size(C.oid)) AS "size"FROM pg_class CLEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)WHERE nspname NOT IN ("pg_catalog", "information_schema")ORDER BY pg_relation_size(C.oid) DESCLIMIT 20;pg_total_relation_size = pg_table_size + pg_indexes_sizepg_table_size = pg_relation_size + toast table + toast indexes + FSM9.0以后:SELECTnspname,relname,relkind as "type",pg_size_pretty(pg_table_size(C.oid)) AS size,pg_size_pretty(pg_indexes_size(C.oid)) AS idxsize,pg_size_pretty(pg_total_relation_size(C.oid)) as "total"FROM pg_class CLEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)WHERE nspname NOT IN ("pg_catalog", "information_schema") ANDnspname !~ "^pg_toast" ANDrelkind IN ("r","i")ORDER BY pg_total_relation_size(C.oid) DESCLIMIT 20;2023-08-05 23:18:221
SQLServer数据库怎么查看表的修改记录
可以尝试如下建议:1、可以使用默认的Log工具或者第三方的(比如:LiteSpeed)的工具。2、做Trace机制,下次出现问题可以溯源。3、一个简单的办法:--Step #1:USE DBNameGOSELECT [Transaction ID], Operation, Context, AllocUnitNameFROM fn_dblog(NULL, NULL) WHERE Operation = "LOP_DELETE_ROWS" and AllocUnitName= "dbo.Test.PK__Test__5F573DD6" -- 这里 "dbo.Test.PK__Test__5F573DD6"指表名的PK_Name -- 可以使用 SP_Pkeys SourceTableName 查到--Step #2:SELECT Operation, [Transaction ID], [Begin Time], [Transaction Name], [Transaction SID]FROM fn_dblog(NULL, NULL)WHERE [Transaction ID] ="0000:0005afba" -- 这里 "0000:0005afba" 指Step #1中的Transaction IDAND [Operation] = "LOP_BEGIN_XACT"--Step #3:USE MASTERGO SELECT SUSER_SNAME(0x01) "UserID" --这里"0000:0005afba" 值Step #2中的Transaction SID2023-08-05 23:18:311
DHCP与BOOTP有什么区别
什么是DHCP? DHCP是Dynamic Host Configuration Protocol(动态主机分配协议)缩写,它的前身是BOOTP。BOOTP原本是用于无磁盘主机连接上的网络上面的:网络主机使用BOOT ROM而不是磁盘启动并连接上网络,BOOTP则可以自动地为那些主机设定TCP/IP环境。但BOOTP有一个缺点:您在设定前须事先获得客户端的硬件地址,而且,与IP的对应是静态的。换而言之,BOOTP非常缺乏“动态性 ”,若在有限的IP资源环境中,BOOTP的一对一对应会造成非常可观的浪费。 DHCP可以说是BOOTP的增强版本,它分为两个部分:一个是服务器端,而另一个是客户端。所有的IP网络设定数据都由DHCP服务器集中管理,并负责处理客户端的DHCP要求;而客户端则会使用从服务器分配下来的IP环境数据。比较BOOTP, DHCP透过“租约”的概念,有效且动态的分配客户端的TCP/IP设定,而且,作为兼容考虑,DHCP也完全照顾了BOOTP Client的需求。 DHCP的分配形式 首先,必须至少有一台DHCP工作在网络上面,它会监听网络的DHCP请求,并与客户端磋商TCP/IP的设定环境。它提供两种IP定位方式: Automatic Allocation 自动分配,其情形是:一旦DHCP客户端第一次成功的从DHCP服务器租用到IP地址之后,就永远使用这个地址。 Dynamic Allocation 动态分配,当DHCP第一次从DHCP服务器租用到IP地址之后,并非永久的使用该地址,只要租约到期,客户端就得释放(release)这个IP地址,以给其他董作站使用。当然,客户端可以比其它主机更优先的更新(renew)租约,或是租用其它的IP地址。 动态分配显然比自动分配更加灵活,尤其是当您的实际IP地址不足的时候,例如:您是一家ISP,只能提供200个IP地址用来给拨接客户,但并不意味着您 的客户最多只能有200个。因为要知道,您的客户们不可能全部同一时间上网的,除了他们各自的行为习惯的不同,也有可能是电话线路的限制。这样,您就可以 将这200个地址,轮流的租用给拨接上来的客户使用了。这也是为什么当您查看IP地址的时候,会因每次拨接而不同的原因了(除非您申请的是一个固定IP, 通常ISP都可以满足这样的要求,这或许要另外收费)。当然,ISP不一定使用DHCP来分配地址,但这个概念和使用IP Pool的原理是一样的。 DHCP除了能动态的设定IP地址之外,还可以将一些IP保留下来给一些特殊用途的机器使用,它可以按照硬件地址来固定的分配IP地址,这样可以给你更大的设计空间。同时,DHCP还可以帮客户指定router、netmask、DNS Server、WINS Server等等项目,您在客户端上面,除了将DHCP选项打勾之外,几乎无需任何的IP环境设定。 DHCP的工作原理 根据客户端是否第一次登录网络,DHCP的工作形式会有所不同。 第一次登录的时候: 寻找Server。当DHCP客户端第一次登录网络的时候,也就是客户发现本机上没有任何IP数据设定,它会向网络发出一个DHCP DISCOVER封包。因为客户端还不知道自己属于哪一个网络,所有封包的来源地址会为0.0.0.0,而目的地址则为255.255.255.255,然后再附上DHCP discover的信息,向网络进行广播。 在Windows的预设情形下,DHCP discover 的等待时间预设为1秒,也就是当客户端将第一个DHCP discover封包送出去之后,在1秒之内没有得到响应的话,就会进行第二次DHCP discover广播。若一直得不到响应的情况下,客户端一共会有四次DHCP discover广播(包括第一次在内),除了第一次会等待1秒外,其余三次的等待时间分别是9、13、16秒。如果都没有得到DHCP服务器的响应,客户端则会显示错误信息,宣告DHCP discover的失败。之后,基于使用者的选择,系统会继续在5分钟之后再重复一次DHCP discover的过程。 提供IP租用地址。当DHCP服务器监听到客户端发出的DHCP discover广播后,它会从那些还没有租出的地址范围内,选择最前面的空置IP,连同其它TCP/IP设定,响应给客户端一个DHCP offer封包。 由于客户端在开始的时候没有IP地址,所以在其DHCP discover封包内会带有其MAC地址信息,并且有一个XID编号来辨别该封包,DHCP服务器响应的DHCP offer封包则会根据这些资料传递给要求租约的客户。根据服务器端的设定,DHCP offer封包会包含一个租约期限的信息。 接收IP租约。如果客户端收到网络上多台DHCP服务器的响应,只会挑选其中一个DHCP offer而已(通常是最先抵达的那个),并且会向网络发送一个DHCP request广播封包,告诉所有DHCP服务器它将指定接收哪一台服务器提供的IP地址。 同时,客户端还会向网络发送一个ARP封包,查询网络上面有没有其它机器使用该IP地址;如果发现该IP已经被占用,客户端则会送出一个DHCP decline封包给DHCP服务器,拒绝接受其DHCP offer,并重新发送DHCP discover信息。 事实上,并不是所有DHCP客户端都会无条件接受DHCP服务器的offer,尤其这些主机安装有其它TCP/IP相关的客户软件。客户端也可以用DHCP request向服务器提出DHCP选择,而这些选择会以不同的号码填写在DHCP Option Field里面: 换一句话说,在DHCP服务器上面的设定,未必是客户端全都接受,客户端可以保留自己的一些TCP/IP设定。而主动权永远在客户端这边。 租约确认。当DHCP服务器接收到客户端的DHCP request之后,会向客户端发出一个DHCP ack响应,以确认IP租约的正式生效,也就结束了一个完整的DHCP工作过程。 DHCP发放流程 第一次登录之后: 一旦DHCP客户端成功地从服务器那里取得DHCP租约之后,除非其租约已经失效并且IP地址也重新设定回0.0.0.0,否则就无需再发送DHCP discover信息了,而会直接使用已经租用到的IP地址向之前的DHCP服务器发出DHCP request信息,DHCP服务器会尽量让客户端使用原来的IP地址,如果没问题的话,直接响应DHCP ack来确认则可。如果该地址已经失效或已经被其他机器使用了,服务器则会响应一个DHCP nack封包给客户端,要求其重新执行DHCP discover。 至于IP的租约期限确实非常考究的,并非如我们租房子那样简单,以NT为例子:DHCP工作站除了在开机的时候发出DHCP request请求之外,在租约期限一半的时候也会发出DHCP request,如果此时得不到DHCP服务器确认的话,工作站还可以继续使用该IP;然后在剩下的租约期限的再一半的时候(即租约的75%),还得不到 确认的话,那么工作站就不能拥有这个IP了。至于为什么不是到租约期限完全结束才放弃IP呢?对不起,小弟也是不学无术之人,没有去深究了,只知道要回答 MCSE题目的时候,您一定要记得NT是这么工作就是了。 要是您想退租,可以随时送出DHCP release命令解约,就算您的租约在前一秒钟才获得的。 跨网络的DHCP运作 从前面描述的过程中,我们不难发现:DHCP discover是以广播方式进行的,其请求只能在同一网络之内进行,因为router是不会将广播传送出去的。但如果DHCP服务器安设在其它的网络上 面呢?由于DHCP客户端还没有IP环境设定,所以也不知道router地址,而且有些router也不会将DHCP广播封包传递出去,因此这情形下 DHCP discover是永远没办法抵达DHCP服务器那端的,当然也不会发生 ,offer及其它动作了。要解决这个问题,我们可以用DHCP Agent( 或 DHCP Proxy )主机来接管客户的DHCP请求,然后将此请求传递给真正的DHCP服务器,然后将服务器的回复传给客户。这里Proxy主机必须自己具有路由能力,且能将双方的封包互传对方。 若不使用Proxy,您也可以在每一个网络之中安装DHCP服务器,但这样的话,一来设备成本会增加,而且管理上面也比较分散。当然喽,如果在一个十分大型的网络中,正阳的均衡式构架还是可取的。视您的实际情况而定了。http://tech.ddvip.com/2008-11/122691202092985.html67和68 Bootp和DHCP UDP上的Bootp/DHCP: 通常DSL和cable-modem的防火墙常会看见大量发送到广播地址255.255.255.255的数据。这些机器在向DHCP服务器请求一个地址 分配。Hacker常进入它们分配一个地址把自己作为局部路由器而发起大量的“中间人”(man-in-middle)攻击。客户端向68端口 (bootps)广播请求配置,服务器向67端口(bootpc)广播回应请求。这种回应使用广播是因为客户端还不知道可以发送的IP地址。 DHCP与Bootp的不同点在于,Bootp也可以完成给主机分配IP地址的任务,但它要求主机的硬件地址必须被手工输入到Bootp表中。可以讲 DHCP看成一个动态的Bootp。但是,要记住的是,Bootp还可以将用来引导主机的操作系统发送给主机。而DHCP不可以。2023-08-05 23:18:412
本地连接一会显示红叉一会又正在连接,这是为什么?
看看网线是不是没插好,把两头换一下看看2023-08-05 23:18:516
java中的JDBC事务和JTA的区别是什么?
在说他们之间的区别之前,先考虑如下几个问题: 1、getCurrentSession()与openSession()的区别? * 采用getCurrentSession()创建的session会绑定到当前线程中,而采用openSession() 创建的session则不会 * 采用getCurrentSession()创建的session在commit或rollback时会自动关闭,而采用openSession() 创建的session必须手动关闭 2、使用getCurrentSession()需要在hibernate.cfg.xml文件中加入如下配置: * 如果使用的是本地事务(jdbc事务) <property name="hibernate.current_session_context_class">thread</property> * 如果使用的是全局事务(jta事务) <property name="hibernate.current_session_context_class">jta</property> 以上是hibernate中一些使用,下面来说说jdbc与jta的区别: JDBC 事务 JDBC 事务是用 Connection 对象控制的。JDBC Connection 接口( java.sql.Connection )提供了两种事务模式:自动提交和手工提交。 #在jdbc中,事务操作缺省是自动提交。也就是说,一条对数据库的更新表达式代表一项事务操作,操作成功后,系统将自动调用commit()来提交,否则将调用rollback()来回滚。 # 在jdbc中,可以通过调用setAutoCommit(false)来禁止自动提交。之后就可以把多个数据库操作的表达式作为一个事务,在操作完成后调 用commit()来进行整体提交,倘若其中一个表达式操作失败,都不会执行到commit(),并且将产生响应的异常;此时就可以在异常捕获时调用 rollback()进行回滚。这样做可以保持多次更新操作后,相关数据的一致性,示例如下: try { conn = DriverManager.getConnection ("jdbc:oracle:thin:@host:1521:SID","username","userpwd"; conn.setAutoCommit(false);//禁止自动提交,设置回滚点 stmt = conn.createStatement(); stmt.executeUpdate(“alter table …”); //数据库更新操作1 stmt.executeUpdate(“insert into table …”); //数据库更新操作2 conn.commit(); //事务提交 }catch(Exception ex) { ex.printStackTrace(); try { conn.rollback(); //操作不成功则回滚 }catch(Exception e) { e.printStackTrace(); } } JDBC 事务的一个缺点是事务的范围局限于一个数据库连接。一个 JDBC 事务不能跨越多个数据库。 JTA事务 JTA(Java Transaction API) 为 J2EE 平台提供了分布式事务服务。 要用 JTA 进行事务界定,应用程序要调用 javax.transaction.UserTransaction 接口中的方法。例如: utx.begin(); // ... DataSource ds = obtainXADataSource(); Connection conn = ds.getConnection(); pstmt = conn.prepareStatement("UPDATE MOVIES ..."); pstmt.setString(1, "Spinal Tap"); pstmt.executeUpdate(); // ... utx.commit(); 让我们来关注下面的话: “用 JTA 界定事务,那么就需要有一个实现 javax.sql.XADataSource 、 javax.sql.XAConnection 和 javax.sql.XAResource 接口的 JDBC 驱动程序。一个实现了这些接口的驱动程序将可以参与 JTA 事务。一个 XADataSource 对象就是一个 XAConnection 对象的工厂。 XAConnection s 是参与 JTA 事务的 JDBC 连接。” 要使用JTA事务,必须使用XADataSource来产生数据库连接,产生的连接为一个XA连接。 XA连接(javax.sql.XAConnection)和非XA(java.sql.Connection)连接的区别在于:XA可以参与JTA的事务,而且不支持自动提交。 注意: Oracle, Sybase, DB2, SQL Server等大型数据库才支持XA, 支持分布事务。 My SQL 连本地都支持不好,更别说分布事务了。 JTA方式的实现过程: 用XADataSource产生的XAConnection它扩展了一个getXAResource()方法,事务通过这个方法把它加入到事务容器中进行 管理.对于调用者来说,根本看不到事务是如果管理的,你只要声明开始事务,告诉容器我下面的操作要求事务参与了,最后告诉事务说到这儿可以提交或回滚了, 别的都是黑箱操作。 在使用JTA之前,你必须首先实现一个Xid类用来标识事务(在普通情况下这将由事务管理程序来处理)。Xid包含三个元素:formatID、gtrid(全局事务标识符)和bqual(分支修饰词标识符)。 下面的例子说明Xid的实现: import javax.transaction.xa.*; public class MyXid implements Xid { protected int formatId; protected byte gtrid[]; protected byte bqual[]; public MyXid() { } public MyXid(int formatId, byte gtrid[], byte bqual[]) { this.formatId = formatId; this.gtrid = gtrid; this.bqual = bqual; } public int getFormatId() { return formatId; } public byte[] getBranchQualifier() { return bqual; } public byte[] getGlobalTransactionId() { return gtrid; } } 其次,你需要创建一个你要使用的数据库的数据源: public DataSource getDataSource() throws SQLException { SQLServerDataSource xaDS = new com.merant.datadirect.jdbcx.sqlserver.SQLServerDataSource(); xaDS.setDataSourceName("SQLServer"); xaDS.setServerName("server"); xaDS.setPortNumber(1433); xaDS.setSelectMethod("cursor"); return xaDS; } 例1 这个例子是用“两步提交协议”来提交一个事务分支: XADataSource xaDS; XAConnection xaCon; XAResource xaRes; Xid xid; Connection con; Statement stmt; int ret; xaDS = getDataSource(); xaCon = xaDS.getXAConnection("jdbc_user", "jdbc_password"); xaRes = xaCon.getXAResource(); con = xaCon.getConnection(); stmt = con.createStatement(); xid = new MyXid(100, new byte[]{0x01}, new byte[]{0x02}); try { xaRes.start(xid, XAResource.TMNOFLAGS); stmt.executeUpdate("insert into test_table values (100)"); xaRes.end(xid, XAResource.TMSUCCESS); ret = xaRes.prepare(xid); if (ret == XAResource.XA_OK) { xaRes.commit(xid, false); } } catch (XAException e) { e.printStackTrace(); } finally { stmt.close(); con.close(); xaCon.close(); } 当然,实际过程中,我们不需要写这些代码,这些代码是JTA最终的实现代码。 关于“两步提交协议”,可以参看下面的文章: http://www.ibm.com/developerworks/cn/db2/library/techarticles/dm-0505weber/index.html两阶段提交(Two-Phase-Commit)协议 首先,两阶段提交(Two-Phase-Commit)事务的启动与常规的单阶段提交(One-Phase-Commit)事务类似。接着,应用程序/客 户机对该两阶段提交(Two-Phase-Commit)操作中所涉及的所有数据库执行其修改工作。现在,在最终提交该事务之前,客户机通知参与的数据库准备提交(第 1 阶段)。如果客户机从数据库收到一条“okay”,就发出命令向数据库提交该事务(第 2 阶段)。最后分布式事务(Distributed Transaction)结束。 上面的例子演示了如何在 Java 中使用 JTA 实现两阶段提交(Two-Phase-Commit)协议。在该应用程序中,如果一个事务分支报告了错误,您就要负责进行错误处理。但是“两阶段提交协议 简介”小节中提到仍然存在一个问题,那就是如果第 2 阶段中一个事务分支发生故障,该怎么办呢? 如果再次查看程序代码,您可以看到在“第 1 阶段”和“第 2 阶段”之间有一个很小的时间间隔。在这一时间间隔中,出于某种理由,其中某一参与数据库可能崩溃。如果发生了,我们将陷入分布式事务已经部分提交的情形中。 假 定下列情形:在“第 1 阶段”之后,您从 DB2 和 IDS 数据库中都收到了“okay”。在下一步中,应用程序成功提交了 DB2 的事务分支。接着,应用程序通知 DB2 事务分支提交事务。现在,在应用程序可以通知 IDS 事务分支提交它这一部分之前,IDS 引擎由于断电发生崩溃。这就是一种部分提交全局事务的情形。您现在该怎么办呢? 在重启之后,DB2 和 IDS 都将尝试恢复打开的事务分支。该引擎等待来自应用程序的提示如何做。如果应用程序没有准备重新发送“第 2 阶段”的提交,该事务分支将被引擎所启动的试探性回滚中止。这是非常糟糕的,因为这将使该全局事务处于不一致状态。 一种解决方案是用一个小型应用程序连接引擎中打开的事务分支,并通知引擎提交或回滚这一打开的事务。如果您使用 IDS 作为后端,那么还有一个隐藏的 onmode 标志,允许您结束打开的事务分支。(onmode -Z xid)。 在 DB2 UDB 中,您可以发出 LIST INDOUBT TRANSACTIONS 来获得打开的 XA 事务的有关信息。您必须查看 DB2 Information Center 中的描述来解决该问题。 上面描述的情形是一个很好的例子,也是使用应用程序服务器(Application Server)或事务监控器(Transaction Monitor)的理由。在使用一个中间层服务器时,就由该服务器负责保持事情正常。2023-08-05 23:19:091
vb下标越界 建了两个OPC组可对改变的值在读入相应数组时报下标越界。请帮忙看下是哪里出了问题,急!!!
断点调试啊,不就行了,哪一句话越界了2023-08-05 23:19:271
如何查看mysql数据库用户密码
用工具如Navicat Premium 打开MySQL数据库的user表里可以看到。连接状态里可以查看用户名程序的配置文件里,有连接数据库的用户名你们。2023-08-05 23:19:3810
哪位兄台能说说TH_GET_SESSION_ID获取的SESSION_ID在SAP中的作用
这位兄台水潜得有点深了,能告诉我你是BASIS还是ABAP开发人员吗?如果是BASIS,能告诉我你 在做什么工作的过程中如何找到的这函数,又打算研究出来干什么用吗? SAP系统里有很多这种ID,除了SESSION_ID以外,还有TRANSACTION_ID,都是用于进程或线程管理 的,在系统中用处很多,但属于接近内核的层面,作为用户而言通常是见不到的,即便是一般的 BASIS维护。所以我想问你找它打算做什么,这样可以更有针对性地回答你的问题。2023-08-05 23:21:531
用VB 编写OPC服务器客户端程序,其中老是出现无效的过程调用或参数,求助!
12023-08-05 23:22:012
微信v3扫码支付二返回的notify.php怎么接收回调的值
其实在写这篇文章的时候感觉自己已经落伍了,不过笔者在百度上搜索"微信支付开发之扫描支付(模式二)后如何回调"寻找答案时,发现依旧有很多朋友没有解决这个问题,所以就把自己的解决思路分享给大家。 一、下载微信支付SDK(笔者以php发开为例,sdk包为WxpayAPI_php_v3.zip)下载SDK包后解压,在解压目录下,我们会看到如下目录二、查阅微信支付开发者文档后得知,微信扫码支付的demo即为example目录下的native.php文件为了方便,我们要做的是将整个解压后的文件放入到本地环境的根目录下的wxpay(可随个人喜好命名)文件夹中三、以笔者为例,在浏览器中输入http://localhost/wxpay/example/native.php打开上面网址后,发现有两个二维码,如题,我们今天研究的是模式二扫码(官方也推荐模式二扫码支付)四、我们用手机登陆微信,扫描上面页面中的模式二的二维码,并且支付在这里我们发现一个有趣的问题,当你支付成功后,PC页面中并没有发生任何变化,所以我们考虑的主要问题是,支付后如何进行回调。 这里不说多的废话了,笔者参考了网上的诸多方法,总结如下: 1、删掉native.php文件中扫码模式一的一些html,只剩下扫码模式二的一些相关html代码。 2、由于官方文档中也说明了,扫码模式二的支付结果是异步响应,不会主动返回支付结果,所以我们采用了javascript去时时监听支付结果,然后根据请求的结果,在做下一步的页面回调。笔者最终代码如下,有兴趣的朋友可以参考下: native.php文件 复制代码 1 <?php 2 ini_set("date.timezone","Asia/Shanghai");3 //error_reporting(E_ERROR); 4 5 require_once "../lib/WxPay.Api.php"; 6 require_once "WxPay.NativePay.php"; 7 require_once "log.php"; 8 9 //模式一 10 /** 11 * 流程: 12 * 1、组装包含支付信息的url,生成二维码13 * 2、用户扫描二维码,进行支付 14 * 3、确定支付之后,微信服务器会回调预先配置的回调地址,在【微信开放平台-微信支付-支付配置】中进行配置15 * 4、在接到回调通知之后,用户进行统一下单支付,并返回支付信息以完成支付(见:native_notify.php)16 * 5、支付完成之后,微信服务器会通知支付成功17 * 6、在支付成功通知中需要查单确认是否真正支付成功(见:notify.php)18 */ 19 $notify = new NativePay(); 20 $url1 = $notify->GetPrePayUrl("123456789");21 22 //模式二 23 /** 24 * 流程: 25 * 1、调用统一下单,取得code_url,生成二维码26 * 2、用户扫描二维码,进行支付 27 * 3、支付完成之后,微信服务器会通知支付成功28 * 4、在支付成功通知中需要查单确认是否真正支付成功(见:notify.php)29 */ 30 $input = new WxPayUnifiedOrder(); 31 $input->SetBody("1分钱购买何宁"); 32 $input->SetAttach("1分钱购买何宁"); 33 $num=WxPayConfig::MCHID.date("YmdHis");34 $input->SetOut_trade_no($num); 35 $input->SetTotal_fee("1"); 36 $input->SetTime_start(date("YmdHis"));37 $input->SetTime_expire(date("YmdHis", time() + 600));38 $input->SetGoods_tag("test"); 39 $input->SetNotify_url("http://paysdk.weixin.qq.com/example/notify.php");40 $input->SetTrade_type("NATIVE"); 41 $input->SetProduct_id("123456789"); 42 $result = $notify->GetPayUrl($input); 43 $url2 = $result["code_url"]; 44 ?> 45 46 <html> 47 <head> 48 <meta http-equiv="content-type" content="text/html;charset=utf-8"/> 49 <meta name="viewport" content="width=device-width, initial-scale=1" /> 50 <title>微信支付样例</title> 51 </head> 52 <body> 53 <div style="margin-left: 10px;color:#556B2F;font-size:30px;font-weight: bolder;">扫描支付模式二</div><br/> 54 <img alt="模式二扫码支付" src="qrcode.php?data=<?php echo urlencode($url2);?>" style="width:150px;height:150px;"/> 55 <div id="myDiv"></div><div id="timer">0</div> 56 <script> 57 //设置每隔1000毫秒执行一次load() 方法58 var myIntval=setInterval(function(){load()},1000);59 function load(){ 60 document.getElementById("timer").innerHTML=parseInt(document.getElementById("timer").innerHTML)+1;61 var xmlhttp; 62 if (window.XMLHttpRequest){ 63 // code for IE7+, Firefox, Chrome, Opera, Safari64 xmlhttp=new XMLHttpRequest();65 }else{ 66 // code for IE6, IE5 67 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");68 } 69 xmlhttp.onreadystatechange=function(){70 if (xmlhttp.readyState==4 && xmlhttp.status==200){71 trade_state=xmlhttp.responseText;72 if(trade_state=="SUCCESS"){73 document.getElementById("myDiv").innerHTML="支付成功";74 //alert(transaction_id);75 //延迟3000毫秒执行tz() 方法76 clearInterval(myIntval);77 setTimeout("location.href="success.php"",3000);78 79 }else if(trade_state=="REFUND"){80 document.getElementById("myDiv").innerHTML="转入退款";81 clearInterval(myIntval);82 }else if(trade_state=="NOTPAY"){83 document.getElementById("myDiv").innerHTML="请扫码支付";84 85 }else if(trade_state=="CLOSED"){86 document.getElementById("myDiv").innerHTML="已关闭";87 clearInterval(myIntval);88 }else if(trade_state=="REVOKED"){89 document.getElementById("myDiv").innerHTML="已撤销";90 clearInterval(myIntval);91 }else if(trade_state=="USERPAYING"){92 document.getElementById("myDiv").innerHTML="用户支付中";93 }else if(trade_state=="PAYERROR"){94 document.getElementById("myDiv").innerHTML="支付失败";95 clearInterval(myIntval);96 } 97 98 } 99 } 100 //orderquery.php 文件返回订单状态,通过订单状态确定支付状态101 xmlhttp.open("POST","orderquery.php",false);102 //下面这句话必须有 103 //把标签/值对添加到要发送的头文件。 104 xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");105 xmlhttp.send("out_trade_no=<?php echo $num;?>");106 107 } 108 </script> 109 110 </body> 111 </html> 复制代码 orderquery.php代码也做了相应调整: <?php ini_set("date.timezone","Asia/Shanghai");error_reporting(E_ERROR); require_once "../lib/WxPay.Api.php"; require_once "log.php"; //初始化日志 $logHandler= new CLogFileHandler("./logs/".date("Y-m-d").".log");$log = Log::Init($logHandler, 15); function printf_info($data) { foreach($data as $key=>$value){ echo "<font color="#f00;">$key</font> : $value <br/>";} } if(isset($_REQUEST["transaction_id"]) && $_REQUEST["transaction_id"] != ""){$transaction_id = $_REQUEST["transaction_id"];$input = new WxPayOrderQuery(); $input->SetTransaction_id($transaction_id);//printf_info(WxPayApi::orderQuery($input));$result=WxPayApi::orderQuery($input); echo $result["trade_state"]; exit(); } if(isset($_REQUEST["out_trade_no"]) && $_REQUEST["out_trade_no"] != ""){$out_trade_no = $_REQUEST["out_trade_no"];$input = new WxPayOrderQuery(); $input->SetOut_trade_no($out_trade_no); //printf_info(WxPayApi::orderQuery($input));$result=WxPayApi::orderQuery($input); echo $result["trade_state"]; exit(); } ?> 新建success.php文件: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>微信支付成功</title> </head> <body> <br /><br /><br /><br /><br /><br /><br /> <h1>微信支付成功</h1> </body> </html>2023-08-05 23:22:111
PHP怎么实现微信申请退款
前面讲了怎么实现微信支付,详见相关文章:PHP实现微信支付(jsapi支付)流程 和ThinkPHP中实现微信支付(jsapi支付)流程。由于业务需求,还需要有微信退款,经过研究和摸索,也终于搞定了。前期准备:当然是搞定了微信支付,不然怎么退款,这次还是使用官方的demo。当然网上可能也有很多大神自己重写和封装了demo,或许更加好用简洁,但是我还是不提倡用,原因如下:(1)可能功能不全,或许他只是实现了微信支付,但是还有申请退款、查询退款、订单查询、撤销订单等业务功能可能是你后续需要的,如果你依赖于大神的SDK的便捷,如果有新的业务需求,你就懵逼了;(2)安全考虑,涉及到支付涉及到金钱,必须要非常安全。官方SDK虽然我也吐槽,但至少会相对比较安全,再次重写,虽然暂时没看出问题,但是万一有漏洞就不好了。本篇还是使用到官方提供的SDK中的最重要的一个类文件WxPay.Api.php中提供的refund()方法来实现,此方法在WxPay.Api.php文件的第141行,代码如下:/** * * 申请退款,WxPayRefund中out_trade_no、transaction_id至少填一个且 * out_refund_no、total_fee、refund_fee、op_user_id为必填参数 * appid、mchid、spbill_create_ip、nonce_str不需要填入 * @param WxPayRefund $inputObj * @param int $timeOut * @throws WxPayException * @return 成功时返回,其他抛异常 */public static function refund($inputObj, $timeOut = 6){$url = "https://api.mch.weixin.qq.com/secapi/pay/refund";//检测必填参数if(!$inputObj->IsOut_trade_noSet() && !$inputObj->IsTransaction_idSet()) {throw new WxPayException("退款申请接口中,out_trade_no、transaction_id至少填一个!");}else if(!$inputObj->IsOut_refund_noSet()){throw new WxPayException("退款申请接口中,缺少必填参数out_refund_no!");}else if(!$inputObj->IsTotal_feeSet()){throw new WxPayException("退款申请接口中,缺少必填参数total_fee!");}else if(!$inputObj->IsRefund_feeSet()){throw new WxPayException("退款申请接口中,缺少必填参数refund_fee!");}else if(!$inputObj->IsOp_user_idSet()){throw new WxPayException("退款申请接口中,缺少必填参数op_user_id!");}$inputObj->SetAppid(WxPayConfig::APPID);//公众账号ID$inputObj->SetMch_id(WxPayConfig::MCHID);//商户号$inputObj->SetNonce_str(self::getNonceStr());//随机字符串$inputObj->SetSign();//签名$xml = $inputObj->ToXml();$startTimeStamp = self::getMillisecond();//请求开始时间$response = self::postXmlCurl($xml, $url, true, $timeOut);$result = WxPayResults::Init($response);self::reportCostTime($url, $startTimeStamp, $result);//上报请求花费时间return $result;}官方的方法,写的很清楚需要哪些参数,还有一些必须参数SDK已经帮我们补齐了,我将这个方法重新封装一下,便于在项目中调用:/** * 微信退款 * @param string $order_id 订单ID * @return 成功时返回(array类型),其他抛异常 */function wxRefund($order_id){//我的SDK放在项目根目录下的Api目录下require_once APP_ROOT."/Api/wxpay/lib/WxPay.Api.php";//查询订单,根据订单里边的数据进行退款$order = M("order")->where(array("id"=>$order_id,"is_refund"=>2,"order_status"=>1))->find();$merchid = WxPayConfig::MCHID;if(!$order) return false;$input = new WxPayRefund();$input->SetOut_trade_no($order["order_sn"]);//自己的订单号$input->SetTransaction_id($order["transaction_id"]); //微信官方生成的订单流水号,在支付成功中有返回$input->SetOut_refund_no(getrand_num(true));//退款单号$input->SetTotal_fee($order["total_price"]);//订单标价金额,单位为分$input->SetRefund_fee($order["total_price"]);//退款总金额,订单总金额,单位为分,只能为整数$input->SetOp_user_id($merchid);$result = WxPayApi::refund($input);//退款操作// 这句file_put_contents是用来查看服务器返回的退款结果 测试完可以删除了//file_put_contents(APP_ROOT."/Api/wxpay/logs/log3.txt",arrayToXml($result),FILE_APPEND);return $result;}这里需要吐槽一下,竟然不说返回值的类型,在支付的时候返回的是XML数据,这里竟然返回的是数组,让我措手不及,哈哈不过还是返回数组比较好,可以直接判断处理。方法调用就更加简单了://微信退款$result = wxRefund($order_id);// 这句file_put_contents是用来查看服务器返回的退款结果 测试完可以删除了//file_put_contents(APP_ROOT."/Api/wxpay/logs/log4.txt",arrayToXml($result),FILE_APPEND);if(($result["return_code"]=="SUCCESS") && ($result["result_code"]=="SUCCESS")){//退款成功}else if(($result["return_code"]=="FAIL") || ($result["result_code"]=="FAIL")){//退款失败//原因$reason = (empty($result["err_code_des"])?$result["return_msg"]:$result["err_code_des"]);}else{//失败}退款成功返回如下:亲测无误:这是集成了官方的SDK实现的,如果不使用SDK,可以使用更简单的方法,见:PHP实现微信支付(jsapi支付)和退款(无需集成支付SDK)更多PHP相关知识,请访问PHP教程!2023-08-05 23:22:181
在oracle中如何找回被删除的数据?
10g及以上,试试看 flashback2023-08-05 23:22:287
怎样把excel的数据导入到数据库里面去
1. 把 excel 另存为 .csv 格式 2. 用 Notepad 打开 .csv 文件, 第一行就是所有的字段 3. 创建表结构 create table yu_rt_01 asselect Transaction_Id,Last_Update_Date,Last_Updated_By,Creation_Date,Created_By,Last_Update_Login,Request_Id,... ,Lcm_Shi 1. 把 excel 另存为 .csv 格式2. 用 Notepad 打开 .csv 文件, 第一行就是所有的字段3. 创建表结构create table yu_rt_01 asselect Transaction_Id,Last_Update_Date,Last_Updated_By,Creation_Date,Created_By,Last_Update_Login,Request_Id,... ,Lcm_Shipment_Line_Idfrom rcv_transactions where 1=2;4. 检查表里面没有数据5. 打开 Toad for Oracle6. 连接数据库7. Database -> Import -> Import Table Data8. 选择表 yu_rt_019. 点击 show data, 现在是空的10. Next11. Import form = text, File 是刚才保存的 .csv 文件12. Next13. First Row 改成 214. 其他所有的保持默认, 点击 commit15. select * from yu_rt_012023-08-05 23:23:451
Session,Dialog和Transaction的区别
会话(Session)跟SDP内信息相关。在SDP中,多媒体会话指的是一组的媒体发送方和接收方及媒体流从发送方流向接受方。会话是由SDP里的user name, session id, network type, address type, 和源处地址元素来确定的。只有当媒体协商成功后,会话才能被建立起来。对话(Dialog)对话指的是一对一的持续一段时间的连接关系,由Call-ID, From-tag和To-tag确定。当三个元素齐全的时候,即对话处于确定阶段时,对话已经建立起来。事务(Transaction)事务包括发送的请求和相应的回应,指的是UA之间的请求和应答关系。而VIA中的branch参数用于确定事务。事务是由事件(方法)来引起的,一个方法(Method)的建立和到来都将建立新的事务。总的来说,1.对话和事务处于信令层,而会话处于媒体传输层。SIP使用SDP来通知传输层(RTP)来创建、增加、移除和修改会话。2.一般来说,在会议应用中SIP可以通过请求来让另一方加入已有会话中。在这种情况下,新的对话会被创建。3.对话是end-point对end-point的关系,即真实的通信双方, 而transaction 是hop by hop的关系,即路由过程中交互的双方。2023-08-05 23:23:531